xref: /titanic_51/usr/src/uts/common/io/nxge/nxge_virtual.c (revision 2bc987325e3ded1865bff043128661815c4690b9)
16f45ec7bSml29623 /*
26f45ec7bSml29623  * CDDL HEADER START
36f45ec7bSml29623  *
46f45ec7bSml29623  * The contents of this file are subject to the terms of the
56f45ec7bSml29623  * Common Development and Distribution License (the "License").
66f45ec7bSml29623  * You may not use this file except in compliance with the License.
76f45ec7bSml29623  *
86f45ec7bSml29623  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96f45ec7bSml29623  * or http://www.opensolaris.org/os/licensing.
106f45ec7bSml29623  * See the License for the specific language governing permissions
116f45ec7bSml29623  * and limitations under the License.
126f45ec7bSml29623  *
136f45ec7bSml29623  * When distributing Covered Code, include this CDDL HEADER in each
146f45ec7bSml29623  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156f45ec7bSml29623  * If applicable, add the following below this CDDL HEADER, with the
166f45ec7bSml29623  * fields enclosed by brackets "[]" replaced with your own identifying
176f45ec7bSml29623  * information: Portions Copyright [yyyy] [name of copyright owner]
186f45ec7bSml29623  *
196f45ec7bSml29623  * CDDL HEADER END
206f45ec7bSml29623  */
216f45ec7bSml29623 /*
229d587972SSantwona Behera  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
236f45ec7bSml29623  */
246f45ec7bSml29623 
256f45ec7bSml29623 #include <sys/nxge/nxge_impl.h>
266f45ec7bSml29623 #include <sys/nxge/nxge_mac.h>
27678453a8Sspeer #include <sys/nxge/nxge_hio.h>
286f45ec7bSml29623 
29952a2464SMichael Speer /*
30952a2464SMichael Speer  * Local defines for FWARC 2006/556
31952a2464SMichael Speer  */
32952a2464SMichael Speer #define	NXGE_NIU_TDMA_PROP_LEN		2
33952a2464SMichael Speer #define	NXGE_NIU_RDMA_PROP_LEN		2
34952a2464SMichael Speer #define	NXGE_NIU_0_INTR_PROP_LEN	19
35952a2464SMichael Speer #define	NXGE_NIU_1_INTR_PROP_LEN	17
36952a2464SMichael Speer 
37952a2464SMichael Speer /*
38952a2464SMichael Speer  * Local functions.
39952a2464SMichael Speer  */
406f45ec7bSml29623 static void nxge_get_niu_property(dev_info_t *, niu_type_t *);
416f45ec7bSml29623 static nxge_status_t nxge_get_mac_addr_properties(p_nxge_t);
426f45ec7bSml29623 static nxge_status_t nxge_use_cfg_n2niu_properties(p_nxge_t);
436f45ec7bSml29623 static void nxge_use_cfg_neptune_properties(p_nxge_t);
446f45ec7bSml29623 static void nxge_use_cfg_dma_config(p_nxge_t);
456f45ec7bSml29623 static void nxge_use_cfg_vlan_class_config(p_nxge_t);
466f45ec7bSml29623 static void nxge_use_cfg_mac_class_config(p_nxge_t);
476f45ec7bSml29623 static void nxge_use_cfg_class_config(p_nxge_t);
486f45ec7bSml29623 static void nxge_use_cfg_link_cfg(p_nxge_t);
496f45ec7bSml29623 static void nxge_set_hw_dma_config(p_nxge_t);
506f45ec7bSml29623 static void nxge_set_hw_vlan_class_config(p_nxge_t);
516f45ec7bSml29623 static void nxge_set_hw_mac_class_config(p_nxge_t);
526f45ec7bSml29623 static void nxge_set_hw_class_config(p_nxge_t);
536f45ec7bSml29623 static nxge_status_t nxge_use_default_dma_config_n2(p_nxge_t);
546f45ec7bSml29623 static void nxge_ldgv_setup(p_nxge_ldg_t *, p_nxge_ldv_t *, uint8_t,
556f45ec7bSml29623 	uint8_t, int *);
5659ac0c16Sdavemq static void nxge_init_mmac(p_nxge_t, boolean_t);
57678453a8Sspeer static void nxge_set_rdc_intr_property(p_nxge_t);
586f45ec7bSml29623 
596f45ec7bSml29623 uint32_t nxge_use_hw_property = 1;
606f45ec7bSml29623 uint32_t nxge_groups_per_port = 2;
616f45ec7bSml29623 
626f45ec7bSml29623 extern uint32_t nxge_use_partition;
636f45ec7bSml29623 extern uint32_t nxge_dma_obp_props_only;
646f45ec7bSml29623 
656f45ec7bSml29623 extern uint_t nxge_rx_intr(void *, void *);
666f45ec7bSml29623 extern uint_t nxge_tx_intr(void *, void *);
676f45ec7bSml29623 extern uint_t nxge_mif_intr(void *, void *);
686f45ec7bSml29623 extern uint_t nxge_mac_intr(void *, void *);
696f45ec7bSml29623 extern uint_t nxge_syserr_intr(void *, void *);
706f45ec7bSml29623 extern void *nxge_list;
716f45ec7bSml29623 
726f45ec7bSml29623 #define	NXGE_SHARED_REG_SW_SIM
736f45ec7bSml29623 
746f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
756f45ec7bSml29623 uint64_t global_dev_ctrl = 0;
766f45ec7bSml29623 #endif
776f45ec7bSml29623 
786f45ec7bSml29623 #define	MAX_SIBLINGS	NXGE_MAX_PORTS
796f45ec7bSml29623 
806f45ec7bSml29623 extern uint32_t nxge_rbr_size;
816f45ec7bSml29623 extern uint32_t nxge_rcr_size;
826f45ec7bSml29623 extern uint32_t nxge_tx_ring_size;
836f45ec7bSml29623 extern uint32_t nxge_rbr_spare_size;
846f45ec7bSml29623 
856f45ec7bSml29623 extern npi_status_t npi_mac_altaddr_disable(npi_handle_t, uint8_t, uint8_t);
866f45ec7bSml29623 
876f45ec7bSml29623 static uint8_t p2_tx_fair[2] = {12, 12};
886f45ec7bSml29623 static uint8_t p2_tx_equal[2] = {12, 12};
896f45ec7bSml29623 static uint8_t p4_tx_fair[4] = {6, 6, 6, 6};
906f45ec7bSml29623 static uint8_t p4_tx_equal[4] = {6, 6, 6, 6};
916f45ec7bSml29623 static uint8_t p2_rx_fair[2] = {8, 8};
926f45ec7bSml29623 static uint8_t p2_rx_equal[2] = {8, 8};
936f45ec7bSml29623 static uint8_t p4_rx_fair[4] = {4, 4, 4, 4};
946f45ec7bSml29623 static uint8_t p4_rx_equal[4] = {4, 4, 4, 4};
956f45ec7bSml29623 
966f45ec7bSml29623 static uint8_t p2_rdcgrp_fair[2] = {4, 4};
976f45ec7bSml29623 static uint8_t p2_rdcgrp_equal[2] = {4, 4};
986f45ec7bSml29623 static uint8_t p4_rdcgrp_fair[4] = {2, 2, 1, 1};
996f45ec7bSml29623 static uint8_t p4_rdcgrp_equal[4] = {2, 2, 2, 2};
1006f45ec7bSml29623 static uint8_t p2_rdcgrp_cls[2] = {1, 1};
1016f45ec7bSml29623 static uint8_t p4_rdcgrp_cls[4] = {1, 1, 1, 1};
1026f45ec7bSml29623 
10359ac0c16Sdavemq static uint8_t rx_4_1G[4] = {4, 4, 4, 4};
10459ac0c16Sdavemq static uint8_t rx_2_10G[2] = {8, 8};
10559ac0c16Sdavemq static uint8_t rx_2_10G_2_1G[4] = {6, 6, 2, 2};
10659ac0c16Sdavemq static uint8_t rx_1_10G_3_1G[4] = {10, 2, 2, 2};
10759ac0c16Sdavemq static uint8_t rx_1_1G_1_10G_2_1G[4] = {2, 10, 2, 2};
10859ac0c16Sdavemq 
10959ac0c16Sdavemq static uint8_t tx_4_1G[4] = {6, 6, 6, 6};
11059ac0c16Sdavemq static uint8_t tx_2_10G[2] = {12, 12};
11159ac0c16Sdavemq static uint8_t tx_2_10G_2_1G[4] = {10, 10, 2, 2};
11259ac0c16Sdavemq static uint8_t tx_1_10G_3_1G[4] = {12, 4, 4, 4};
11359ac0c16Sdavemq static uint8_t tx_1_1G_1_10G_2_1G[4] = {4, 12, 4, 4};
11459ac0c16Sdavemq 
1156f45ec7bSml29623 typedef enum {
1166f45ec7bSml29623 	DEFAULT = 0,
1176f45ec7bSml29623 	EQUAL,
1186f45ec7bSml29623 	FAIR,
1196f45ec7bSml29623 	CUSTOM,
1206f45ec7bSml29623 	CLASSIFY,
1216f45ec7bSml29623 	L2_CLASSIFY,
1226f45ec7bSml29623 	L3_DISTRIBUTE,
1236f45ec7bSml29623 	L3_CLASSIFY,
1246f45ec7bSml29623 	L3_TCAM,
1256f45ec7bSml29623 	CONFIG_TOKEN_NONE
1266f45ec7bSml29623 } config_token_t;
1276f45ec7bSml29623 
1286f45ec7bSml29623 static char *token_names[] = {
1296f45ec7bSml29623 	"default",
1306f45ec7bSml29623 	"equal",
1316f45ec7bSml29623 	"fair",
1326f45ec7bSml29623 	"custom",
1336f45ec7bSml29623 	"classify",
1346f45ec7bSml29623 	"l2_classify",
1356f45ec7bSml29623 	"l3_distribute",
1366f45ec7bSml29623 	"l3_classify",
1376f45ec7bSml29623 	"l3_tcam",
1386f45ec7bSml29623 	"none",
1396f45ec7bSml29623 };
1406f45ec7bSml29623 
1416f45ec7bSml29623 void nxge_virint_regs_dump(p_nxge_t nxgep);
1426f45ec7bSml29623 
1436f45ec7bSml29623 void
1446f45ec7bSml29623 nxge_virint_regs_dump(p_nxge_t nxgep)
1456f45ec7bSml29623 {
1466f45ec7bSml29623 	npi_handle_t handle;
1476f45ec7bSml29623 
1486f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_virint_regs_dump"));
1496f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
1506f45ec7bSml29623 	(void) npi_vir_dump_pio_fzc_regs_one(handle);
1516f45ec7bSml29623 	(void) npi_vir_dump_ldgnum(handle);
1526f45ec7bSml29623 	(void) npi_vir_dump_ldsv(handle);
1536f45ec7bSml29623 	(void) npi_vir_dump_imask0(handle);
1546f45ec7bSml29623 	(void) npi_vir_dump_sid(handle);
1556f45ec7bSml29623 	(void) npi_mac_dump_regs(handle, nxgep->function_num);
1566f45ec7bSml29623 	(void) npi_ipp_dump_regs(handle, nxgep->function_num);
1576f45ec7bSml29623 	(void) npi_fflp_dump_regs(handle);
1586f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_virint_regs_dump"));
1596f45ec7bSml29623 }
1606f45ec7bSml29623 
1616f45ec7bSml29623 /*
1626f45ec7bSml29623  * For now: we hard coded the DMA configurations.
1636f45ec7bSml29623  *	    and assume for one partition only.
1646f45ec7bSml29623  *
1656f45ec7bSml29623  *       OBP. Then OBP will pass this partition's
1666f45ec7bSml29623  *	 Neptune configurations to fcode to create
1676f45ec7bSml29623  *	 properties for them.
1686f45ec7bSml29623  *
1696f45ec7bSml29623  *	Since Neptune(PCI-E) and NIU (Niagara-2) has
1706f45ec7bSml29623  *	different bus interfaces, the driver needs
1716f45ec7bSml29623  *	to know which bus it is connected to.
1726f45ec7bSml29623  *  	Ravinder suggested: create a device property.
1736f45ec7bSml29623  *	In partitioning environment, we cannot
1746f45ec7bSml29623  *	use .conf file (need to check). If conf changes,
1756f45ec7bSml29623  *	need to reboot the system.
1766f45ec7bSml29623  *	The following function assumes that we will
1776f45ec7bSml29623  *	retrieve its properties from a virtualized nexus driver.
1786f45ec7bSml29623  */
1796f45ec7bSml29623 
1806f45ec7bSml29623 nxge_status_t
1816f45ec7bSml29623 nxge_cntlops(dev_info_t *dip, nxge_ctl_enum_t ctlop, void *arg, void *result)
1826f45ec7bSml29623 {
1836f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
1846f45ec7bSml29623 	int instance;
1856f45ec7bSml29623 	p_nxge_t nxgep;
1866f45ec7bSml29623 
1876f45ec7bSml29623 #ifndef NXGE_SHARED_REG_SW_SIM
1886f45ec7bSml29623 	npi_handle_t handle;
1896f45ec7bSml29623 	uint16_t sr16, cr16;
1906f45ec7bSml29623 #endif
1916f45ec7bSml29623 	instance = ddi_get_instance(dip);
1926f45ec7bSml29623 	NXGE_DEBUG_MSG((NULL, VIR_CTL, "Instance %d ", instance));
1936f45ec7bSml29623 
1946f45ec7bSml29623 	if (nxge_list == NULL) {
1956f45ec7bSml29623 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
1966f45ec7bSml29623 		    "nxge_cntlops: nxge_list null"));
1976f45ec7bSml29623 		return (NXGE_ERROR);
1986f45ec7bSml29623 	}
1996f45ec7bSml29623 	nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance);
2006f45ec7bSml29623 	if (nxgep == NULL) {
2016f45ec7bSml29623 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
2026f45ec7bSml29623 		    "nxge_cntlops: nxgep null"));
2036f45ec7bSml29623 		return (NXGE_ERROR);
2046f45ec7bSml29623 	}
2056f45ec7bSml29623 #ifndef NXGE_SHARED_REG_SW_SIM
2066f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
2076f45ec7bSml29623 #endif
2086f45ec7bSml29623 	switch (ctlop) {
2096f45ec7bSml29623 	case NXGE_CTLOPS_NIUTYPE:
2106f45ec7bSml29623 		nxge_get_niu_property(dip, (niu_type_t *)result);
2116f45ec7bSml29623 		return (status);
2126f45ec7bSml29623 
2136f45ec7bSml29623 	case NXGE_CTLOPS_GET_SHARED_REG:
2146f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
2156f45ec7bSml29623 		*(uint64_t *)result = global_dev_ctrl;
2166f45ec7bSml29623 		return (0);
2176f45ec7bSml29623 #else
2186f45ec7bSml29623 		status = npi_dev_func_sr_sr_get(handle, &sr16);
2196f45ec7bSml29623 		*(uint16_t *)result = sr16;
2206f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
2216f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_GET_SHARED_REG"));
2226f45ec7bSml29623 		return (0);
2236f45ec7bSml29623 #endif
2246f45ec7bSml29623 
2256f45ec7bSml29623 	case NXGE_CTLOPS_SET_SHARED_REG_LOCK:
2266f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
2276f45ec7bSml29623 		global_dev_ctrl = *(uint64_t *)arg;
2286f45ec7bSml29623 		return (0);
2296f45ec7bSml29623 #else
2306f45ec7bSml29623 		status = NPI_FAILURE;
2316f45ec7bSml29623 		while (status != NPI_SUCCESS)
2326f45ec7bSml29623 			status = npi_dev_func_sr_lock_enter(handle);
2336f45ec7bSml29623 
2346f45ec7bSml29623 		sr16 = *(uint16_t *)arg;
2356f45ec7bSml29623 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
2366f45ec7bSml29623 		status = npi_dev_func_sr_lock_free(handle);
2376f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
2386f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
2396f45ec7bSml29623 		return (0);
2406f45ec7bSml29623 #endif
2416f45ec7bSml29623 
2426f45ec7bSml29623 	case NXGE_CTLOPS_UPDATE_SHARED_REG:
2436f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
2446f45ec7bSml29623 		global_dev_ctrl |= *(uint64_t *)arg;
2456f45ec7bSml29623 		return (0);
2466f45ec7bSml29623 #else
2476f45ec7bSml29623 		status = NPI_FAILURE;
2486f45ec7bSml29623 		while (status != NPI_SUCCESS)
2496f45ec7bSml29623 			status = npi_dev_func_sr_lock_enter(handle);
2506f45ec7bSml29623 		status = npi_dev_func_sr_sr_get(handle, &sr16);
2516f45ec7bSml29623 		sr16 |= *(uint16_t *)arg;
2526f45ec7bSml29623 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
2536f45ec7bSml29623 		status = npi_dev_func_sr_lock_free(handle);
2546f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
2556f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
2566f45ec7bSml29623 		return (0);
2576f45ec7bSml29623 #endif
2586f45ec7bSml29623 
2596f45ec7bSml29623 	case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG_UL:
2606f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
2616f45ec7bSml29623 		global_dev_ctrl |= *(uint64_t *)arg;
2626f45ec7bSml29623 		return (0);
2636f45ec7bSml29623 #else
2646f45ec7bSml29623 		status = npi_dev_func_sr_sr_get(handle, &sr16);
2656f45ec7bSml29623 		cr16 = *(uint16_t *)arg;
2666f45ec7bSml29623 		sr16 &= ~cr16;
2676f45ec7bSml29623 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
2686f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
2696f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
2706f45ec7bSml29623 		return (0);
2716f45ec7bSml29623 #endif
2726f45ec7bSml29623 
2736f45ec7bSml29623 	case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG:
2746f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
2756f45ec7bSml29623 		global_dev_ctrl |= *(uint64_t *)arg;
2766f45ec7bSml29623 		return (0);
2776f45ec7bSml29623 #else
2786f45ec7bSml29623 		status = NPI_FAILURE;
2796f45ec7bSml29623 		while (status != NPI_SUCCESS)
2806f45ec7bSml29623 			status = npi_dev_func_sr_lock_enter(handle);
2816f45ec7bSml29623 		status = npi_dev_func_sr_sr_get(handle, &sr16);
2826f45ec7bSml29623 		cr16 = *(uint16_t *)arg;
2836f45ec7bSml29623 		sr16 &= ~cr16;
2846f45ec7bSml29623 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
2856f45ec7bSml29623 		status = npi_dev_func_sr_lock_free(handle);
2866f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
2876f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
2886f45ec7bSml29623 		return (0);
2896f45ec7bSml29623 #endif
2906f45ec7bSml29623 
2916f45ec7bSml29623 	case NXGE_CTLOPS_GET_LOCK_BLOCK:
2926f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
2936f45ec7bSml29623 		global_dev_ctrl |= *(uint64_t *)arg;
2946f45ec7bSml29623 		return (0);
2956f45ec7bSml29623 #else
2966f45ec7bSml29623 		status = NPI_FAILURE;
2976f45ec7bSml29623 		while (status != NPI_SUCCESS)
2986f45ec7bSml29623 			status = npi_dev_func_sr_lock_enter(handle);
2996f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
3006f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_BLOCK"));
3016f45ec7bSml29623 		return (0);
3026f45ec7bSml29623 #endif
3036f45ec7bSml29623 	case NXGE_CTLOPS_GET_LOCK_TRY:
3046f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
3056f45ec7bSml29623 		global_dev_ctrl |= *(uint64_t *)arg;
3066f45ec7bSml29623 		return (0);
3076f45ec7bSml29623 #else
3086f45ec7bSml29623 		status = npi_dev_func_sr_lock_enter(handle);
3096f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
3106f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_TRY"));
3116f45ec7bSml29623 		if (status == NPI_SUCCESS)
3126f45ec7bSml29623 			return (NXGE_OK);
3136f45ec7bSml29623 		else
3146f45ec7bSml29623 			return (NXGE_ERROR);
3156f45ec7bSml29623 #endif
3166f45ec7bSml29623 	case NXGE_CTLOPS_FREE_LOCK:
3176f45ec7bSml29623 #ifdef NXGE_SHARED_REG_SW_SIM
3186f45ec7bSml29623 		global_dev_ctrl |= *(uint64_t *)arg;
3196f45ec7bSml29623 		return (0);
3206f45ec7bSml29623 #else
3216f45ec7bSml29623 		status = npi_dev_func_sr_lock_free(handle);
3226f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
3236f45ec7bSml29623 		    "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_FREE"));
3246f45ec7bSml29623 		if (status == NPI_SUCCESS)
3256f45ec7bSml29623 			return (NXGE_OK);
3266f45ec7bSml29623 		else
3276f45ec7bSml29623 			return (NXGE_ERROR);
3286f45ec7bSml29623 #endif
3296f45ec7bSml29623 
3306f45ec7bSml29623 	default:
3316f45ec7bSml29623 		status = NXGE_ERROR;
3326f45ec7bSml29623 	}
3336f45ec7bSml29623 
3346f45ec7bSml29623 	return (status);
3356f45ec7bSml29623 }
3366f45ec7bSml29623 
3376f45ec7bSml29623 void
3386f45ec7bSml29623 nxge_common_lock_get(p_nxge_t nxgep)
3396f45ec7bSml29623 {
3406f45ec7bSml29623 	uint32_t status = NPI_FAILURE;
3416f45ec7bSml29623 	npi_handle_t handle;
3426f45ec7bSml29623 
3436f45ec7bSml29623 #if	defined(NXGE_SHARE_REG_SW_SIM)
3446f45ec7bSml29623 	return;
3456f45ec7bSml29623 #endif
3466f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
3476f45ec7bSml29623 	while (status != NPI_SUCCESS)
3486f45ec7bSml29623 		status = npi_dev_func_sr_lock_enter(handle);
3496f45ec7bSml29623 }
3506f45ec7bSml29623 
3516f45ec7bSml29623 void
3526f45ec7bSml29623 nxge_common_lock_free(p_nxge_t nxgep)
3536f45ec7bSml29623 {
3546f45ec7bSml29623 	npi_handle_t handle;
3556f45ec7bSml29623 
3566f45ec7bSml29623 #if	defined(NXGE_SHARE_REG_SW_SIM)
3576f45ec7bSml29623 	return;
3586f45ec7bSml29623 #endif
3596f45ec7bSml29623 	handle = nxgep->npi_reg_handle;
3606f45ec7bSml29623 	(void) npi_dev_func_sr_lock_free(handle);
3616f45ec7bSml29623 }
3626f45ec7bSml29623 
36356d930aeSspeer 
3646f45ec7bSml29623 static void
3656f45ec7bSml29623 nxge_get_niu_property(dev_info_t *dip, niu_type_t *niu_type)
3666f45ec7bSml29623 {
3676f45ec7bSml29623 	uchar_t *prop_val;
3686f45ec7bSml29623 	uint_t prop_len;
3696f45ec7bSml29623 
37059ac0c16Sdavemq 	*niu_type = NIU_TYPE_NONE;
3716f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0,
3726f45ec7bSml29623 	    "niu-type", (uchar_t **)&prop_val,
3736f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
3746f45ec7bSml29623 		if (strncmp("niu", (caddr_t)prop_val, (size_t)prop_len) == 0) {
3756f45ec7bSml29623 			*niu_type = N2_NIU;
3766f45ec7bSml29623 		}
3776f45ec7bSml29623 		ddi_prop_free(prop_val);
3786f45ec7bSml29623 	}
3796f45ec7bSml29623 }
3806f45ec7bSml29623 
3816f45ec7bSml29623 static config_token_t
3826f45ec7bSml29623 nxge_get_config_token(char *prop)
3836f45ec7bSml29623 {
3846f45ec7bSml29623 	config_token_t token = DEFAULT;
3856f45ec7bSml29623 
3866f45ec7bSml29623 	while (token < CONFIG_TOKEN_NONE) {
3876f45ec7bSml29623 		if (strncmp(prop, token_names[token], 4) == 0)
3886f45ec7bSml29623 			break;
3896f45ec7bSml29623 		token++;
3906f45ec7bSml29623 	}
3916f45ec7bSml29623 	return (token);
3926f45ec7bSml29623 }
3936f45ec7bSml29623 
3946f45ec7bSml29623 /* per port */
3956f45ec7bSml29623 
3966f45ec7bSml29623 static nxge_status_t
3976f45ec7bSml29623 nxge_update_rxdma_grp_properties(p_nxge_t nxgep, config_token_t token,
3986f45ec7bSml29623 	dev_info_t *s_dip[])
3996f45ec7bSml29623 {
4006f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
4016f45ec7bSml29623 	int ddi_status;
4026f45ec7bSml29623 	int num_ports = nxgep->nports;
4036f45ec7bSml29623 	int port, bits, j;
4046f45ec7bSml29623 	uint8_t start_grp = 0, num_grps = 0;
4056f45ec7bSml29623 	p_nxge_param_t param_arr;
4066f45ec7bSml29623 	uint32_t grp_bitmap[MAX_SIBLINGS];
4076f45ec7bSml29623 	int custom_start_grp[MAX_SIBLINGS];
4086f45ec7bSml29623 	int custom_num_grp[MAX_SIBLINGS];
4096f45ec7bSml29623 	uint8_t bad_config = B_FALSE;
4106f45ec7bSml29623 	char *start_prop, *num_prop, *cfg_prop;
4116f45ec7bSml29623 
4126f45ec7bSml29623 	start_grp = 0;
4136f45ec7bSml29623 	param_arr = nxgep->param_arr;
4146f45ec7bSml29623 	start_prop = param_arr[param_rdc_grps_start].fcode_name;
4156f45ec7bSml29623 	num_prop = param_arr[param_rx_rdc_grps].fcode_name;
4166f45ec7bSml29623 
4176f45ec7bSml29623 	switch (token) {
4186f45ec7bSml29623 	case FAIR:
4196f45ec7bSml29623 		cfg_prop = "fair";
4206f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
4216f45ec7bSml29623 			custom_num_grp[port] =
4226f45ec7bSml29623 			    (num_ports == 4) ?
4236f45ec7bSml29623 			    p4_rdcgrp_fair[port] :
4246f45ec7bSml29623 			    p2_rdcgrp_fair[port];
4256f45ec7bSml29623 			custom_start_grp[port] = start_grp;
4266f45ec7bSml29623 			start_grp += custom_num_grp[port];
4276f45ec7bSml29623 		}
4286f45ec7bSml29623 		break;
4296f45ec7bSml29623 
4306f45ec7bSml29623 	case EQUAL:
4316f45ec7bSml29623 		cfg_prop = "equal";
4326f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
4336f45ec7bSml29623 			custom_num_grp[port] =
4346f45ec7bSml29623 			    (num_ports == 4) ?
4356f45ec7bSml29623 			    p4_rdcgrp_equal[port] :
4366f45ec7bSml29623 			    p2_rdcgrp_equal[port];
4376f45ec7bSml29623 			custom_start_grp[port] = start_grp;
4386f45ec7bSml29623 			start_grp += custom_num_grp[port];
4396f45ec7bSml29623 		}
4406f45ec7bSml29623 		break;
4416f45ec7bSml29623 
4426f45ec7bSml29623 
4436f45ec7bSml29623 	case CLASSIFY:
4446f45ec7bSml29623 		cfg_prop = "classify";
4456f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
4466f45ec7bSml29623 			custom_num_grp[port] = (num_ports == 4) ?
4476f45ec7bSml29623 			    p4_rdcgrp_cls[port] : p2_rdcgrp_cls[port];
4486f45ec7bSml29623 			custom_start_grp[port] = start_grp;
4496f45ec7bSml29623 			start_grp += custom_num_grp[port];
4506f45ec7bSml29623 		}
4516f45ec7bSml29623 		break;
4526f45ec7bSml29623 
4536f45ec7bSml29623 	case CUSTOM:
4546f45ec7bSml29623 		cfg_prop = "custom";
4556f45ec7bSml29623 		/* See if it is good config */
4566f45ec7bSml29623 		num_grps = 0;
4576f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
4586f45ec7bSml29623 			custom_start_grp[port] =
4596f45ec7bSml29623 			    ddi_prop_get_int(DDI_DEV_T_NONE, s_dip[port],
4606f45ec7bSml29623 			    DDI_PROP_DONTPASS, start_prop, -1);
4616f45ec7bSml29623 			if ((custom_start_grp[port] == -1) ||
4626f45ec7bSml29623 			    (custom_start_grp[port] >=
4636f45ec7bSml29623 			    NXGE_MAX_RDC_GRPS)) {
4646f45ec7bSml29623 				bad_config = B_TRUE;
4656f45ec7bSml29623 				break;
4666f45ec7bSml29623 			}
4676f45ec7bSml29623 			custom_num_grp[port] = ddi_prop_get_int(
4686f45ec7bSml29623 			    DDI_DEV_T_NONE,
4696f45ec7bSml29623 			    s_dip[port],
4706f45ec7bSml29623 			    DDI_PROP_DONTPASS,
4716f45ec7bSml29623 			    num_prop, -1);
4726f45ec7bSml29623 
4736f45ec7bSml29623 			if ((custom_num_grp[port] == -1) ||
4746f45ec7bSml29623 			    (custom_num_grp[port] >
4756f45ec7bSml29623 			    NXGE_MAX_RDC_GRPS) ||
4766f45ec7bSml29623 			    ((custom_num_grp[port] +
4776f45ec7bSml29623 			    custom_start_grp[port]) >=
4786f45ec7bSml29623 			    NXGE_MAX_RDC_GRPS)) {
4796f45ec7bSml29623 				bad_config = B_TRUE;
4806f45ec7bSml29623 				break;
4816f45ec7bSml29623 			}
4826f45ec7bSml29623 			num_grps += custom_num_grp[port];
4836f45ec7bSml29623 			if (num_grps > NXGE_MAX_RDC_GRPS) {
4846f45ec7bSml29623 				bad_config = B_TRUE;
4856f45ec7bSml29623 				break;
4866f45ec7bSml29623 			}
4876f45ec7bSml29623 			grp_bitmap[port] = 0;
4886f45ec7bSml29623 			for (bits = 0;
4896f45ec7bSml29623 			    bits < custom_num_grp[port];
4906f45ec7bSml29623 			    bits++) {
4916f45ec7bSml29623 				grp_bitmap[port] |=
4926f45ec7bSml29623 				    (1 << (bits + custom_start_grp[port]));
4936f45ec7bSml29623 			}
4946f45ec7bSml29623 
4956f45ec7bSml29623 		}
4966f45ec7bSml29623 
4976f45ec7bSml29623 		if (bad_config == B_FALSE) {
4986f45ec7bSml29623 			/* check for overlap */
4996f45ec7bSml29623 			for (port = 0; port < num_ports - 1; port++) {
5006f45ec7bSml29623 				for (j = port + 1; j < num_ports; j++) {
5016f45ec7bSml29623 					if (grp_bitmap[port] &
5026f45ec7bSml29623 					    grp_bitmap[j]) {
5036f45ec7bSml29623 						bad_config = B_TRUE;
5046f45ec7bSml29623 						break;
5056f45ec7bSml29623 					}
5066f45ec7bSml29623 				}
5076f45ec7bSml29623 				if (bad_config == B_TRUE)
5086f45ec7bSml29623 					break;
5096f45ec7bSml29623 			}
5106f45ec7bSml29623 		}
5116f45ec7bSml29623 		if (bad_config == B_TRUE) {
5126f45ec7bSml29623 			/* use default config */
5136f45ec7bSml29623 			for (port = 0; port < num_ports; port++) {
5146f45ec7bSml29623 				custom_num_grp[port] =
5156f45ec7bSml29623 				    (num_ports == 4) ?
5166f45ec7bSml29623 				    p4_rx_fair[port] : p2_rx_fair[port];
5176f45ec7bSml29623 				custom_start_grp[port] = start_grp;
5186f45ec7bSml29623 				start_grp += custom_num_grp[port];
5196f45ec7bSml29623 			}
5206f45ec7bSml29623 		}
5216f45ec7bSml29623 		break;
5226f45ec7bSml29623 
5236f45ec7bSml29623 	default:
5246f45ec7bSml29623 		/* use default config */
5256f45ec7bSml29623 		cfg_prop = "fair";
5266f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
5276f45ec7bSml29623 			custom_num_grp[port] = (num_ports == 4) ?
5286f45ec7bSml29623 			    p4_rx_fair[port] : p2_rx_fair[port];
5296f45ec7bSml29623 			custom_start_grp[port] = start_grp;
5306f45ec7bSml29623 			start_grp += custom_num_grp[port];
5316f45ec7bSml29623 		}
5326f45ec7bSml29623 		break;
5336f45ec7bSml29623 	}
5346f45ec7bSml29623 
5356f45ec7bSml29623 	/* Now Update the rx properties */
5366f45ec7bSml29623 	for (port = 0; port < num_ports; port++) {
5376f45ec7bSml29623 		ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port],
5386f45ec7bSml29623 		    "rxdma-grp-cfg", cfg_prop);
5396f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
5406f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5416f45ec7bSml29623 			    " property %s not updating",
5426f45ec7bSml29623 			    cfg_prop));
5436f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
5446f45ec7bSml29623 		}
5456f45ec7bSml29623 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
5466f45ec7bSml29623 		    num_prop, custom_num_grp[port]);
5476f45ec7bSml29623 
5486f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
5496f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5506f45ec7bSml29623 			    " property %s not updating",
5516f45ec7bSml29623 			    num_prop));
5526f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
5536f45ec7bSml29623 		}
5546f45ec7bSml29623 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
5556f45ec7bSml29623 		    start_prop, custom_start_grp[port]);
5566f45ec7bSml29623 
5576f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
5586f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
5596f45ec7bSml29623 			    " property %s not updating",
5606f45ec7bSml29623 			    start_prop));
5616f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
5626f45ec7bSml29623 		}
5636f45ec7bSml29623 	}
5646f45ec7bSml29623 	if (status & NXGE_DDI_FAILED)
5656f45ec7bSml29623 		status |= NXGE_ERROR;
5666f45ec7bSml29623 
5676f45ec7bSml29623 	return (status);
5686f45ec7bSml29623 }
5696f45ec7bSml29623 
5706f45ec7bSml29623 static nxge_status_t
5716f45ec7bSml29623 nxge_update_rxdma_properties(p_nxge_t nxgep, config_token_t token,
5726f45ec7bSml29623 	dev_info_t *s_dip[])
5736f45ec7bSml29623 {
5746f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
5756f45ec7bSml29623 	int ddi_status;
5766f45ec7bSml29623 	int num_ports = nxgep->nports;
5776f45ec7bSml29623 	int port, bits, j;
5786f45ec7bSml29623 	uint8_t start_rdc = 0, num_rdc = 0;
5796f45ec7bSml29623 	p_nxge_param_t param_arr;
5806f45ec7bSml29623 	uint32_t rdc_bitmap[MAX_SIBLINGS];
5816f45ec7bSml29623 	int custom_start_rdc[MAX_SIBLINGS];
5826f45ec7bSml29623 	int custom_num_rdc[MAX_SIBLINGS];
5836f45ec7bSml29623 	uint8_t bad_config = B_FALSE;
5846f45ec7bSml29623 	int *prop_val;
5856f45ec7bSml29623 	uint_t prop_len;
5866f45ec7bSml29623 	char *start_rdc_prop, *num_rdc_prop, *cfg_prop;
5876f45ec7bSml29623 
5886f45ec7bSml29623 	start_rdc = 0;
5896f45ec7bSml29623 	param_arr = nxgep->param_arr;
5906f45ec7bSml29623 	start_rdc_prop = param_arr[param_rxdma_channels_begin].fcode_name;
5916f45ec7bSml29623 	num_rdc_prop = param_arr[param_rxdma_channels].fcode_name;
5926f45ec7bSml29623 
5936f45ec7bSml29623 	switch (token) {
5946f45ec7bSml29623 	case FAIR:
5956f45ec7bSml29623 		cfg_prop = "fair";
5966f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
5976f45ec7bSml29623 			custom_num_rdc[port] = (num_ports == 4) ?
5986f45ec7bSml29623 			    p4_rx_fair[port] : p2_rx_fair[port];
5996f45ec7bSml29623 			custom_start_rdc[port] = start_rdc;
6006f45ec7bSml29623 			start_rdc += custom_num_rdc[port];
6016f45ec7bSml29623 		}
6026f45ec7bSml29623 		break;
6036f45ec7bSml29623 
6046f45ec7bSml29623 	case EQUAL:
6056f45ec7bSml29623 		cfg_prop = "equal";
6066f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
6076f45ec7bSml29623 			custom_num_rdc[port] = (num_ports == 4) ?
6086f45ec7bSml29623 			    p4_rx_equal[port] :
6096f45ec7bSml29623 			    p2_rx_equal[port];
6106f45ec7bSml29623 			custom_start_rdc[port] = start_rdc;
6116f45ec7bSml29623 			start_rdc += custom_num_rdc[port];
6126f45ec7bSml29623 		}
6136f45ec7bSml29623 		break;
6146f45ec7bSml29623 
6156f45ec7bSml29623 	case CUSTOM:
6166f45ec7bSml29623 		cfg_prop = "custom";
6176f45ec7bSml29623 		/* See if it is good config */
6186f45ec7bSml29623 		num_rdc = 0;
6196f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
6206f45ec7bSml29623 			ddi_status = ddi_prop_lookup_int_array(
6216f45ec7bSml29623 			    DDI_DEV_T_ANY,
6226f45ec7bSml29623 			    s_dip[port], 0,
6236f45ec7bSml29623 			    start_rdc_prop,
6246f45ec7bSml29623 			    &prop_val,
6256f45ec7bSml29623 			    &prop_len);
6266f45ec7bSml29623 			if (ddi_status == DDI_SUCCESS)
6276f45ec7bSml29623 				custom_start_rdc[port] = *prop_val;
6286f45ec7bSml29623 			else {
6296f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
6306f45ec7bSml29623 				    " %s custom start port %d"
6316f45ec7bSml29623 				    " read failed ",
6326f45ec7bSml29623 				    " rxdma-cfg", port));
6336f45ec7bSml29623 				bad_config = B_TRUE;
6346f45ec7bSml29623 				status |= NXGE_DDI_FAILED;
6356f45ec7bSml29623 			}
6366f45ec7bSml29623 			if ((custom_start_rdc[port] == -1) ||
6376f45ec7bSml29623 			    (custom_start_rdc[port] >=
6386f45ec7bSml29623 			    NXGE_MAX_RDCS)) {
6396f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
6406f45ec7bSml29623 				    " %s custom start %d"
6416f45ec7bSml29623 				    " out of range %x ",
6426f45ec7bSml29623 				    " rxdma-cfg",
6436f45ec7bSml29623 				    port,
6446f45ec7bSml29623 				    custom_start_rdc[port]));
6456f45ec7bSml29623 				bad_config = B_TRUE;
6466f45ec7bSml29623 				break;
6476f45ec7bSml29623 			}
6486f45ec7bSml29623 			ddi_status = ddi_prop_lookup_int_array(
6496f45ec7bSml29623 			    DDI_DEV_T_ANY,
6506f45ec7bSml29623 			    s_dip[port],
6516f45ec7bSml29623 			    0,
6526f45ec7bSml29623 			    num_rdc_prop,
6536f45ec7bSml29623 			    &prop_val,
6546f45ec7bSml29623 			    &prop_len);
6556f45ec7bSml29623 
6566f45ec7bSml29623 			if (ddi_status == DDI_SUCCESS)
6576f45ec7bSml29623 				custom_num_rdc[port] = *prop_val;
6586f45ec7bSml29623 			else {
6596f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
6606f45ec7bSml29623 				    " %s custom num port %d"
6616f45ec7bSml29623 				    " read failed ",
6626f45ec7bSml29623 				    "rxdma-cfg", port));
6636f45ec7bSml29623 				bad_config = B_TRUE;
6646f45ec7bSml29623 				status |= NXGE_DDI_FAILED;
6656f45ec7bSml29623 			}
6666f45ec7bSml29623 
6676f45ec7bSml29623 			if ((custom_num_rdc[port] == -1) ||
6686f45ec7bSml29623 			    (custom_num_rdc[port] >
6696f45ec7bSml29623 			    NXGE_MAX_RDCS) ||
6706f45ec7bSml29623 			    ((custom_num_rdc[port] +
6716f45ec7bSml29623 			    custom_start_rdc[port]) >
6726f45ec7bSml29623 			    NXGE_MAX_RDCS)) {
6736f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
6746f45ec7bSml29623 				    " %s custom num %d"
6756f45ec7bSml29623 				    " out of range %x ",
6766f45ec7bSml29623 				    " rxdma-cfg",
6776f45ec7bSml29623 				    port, custom_num_rdc[port]));
6786f45ec7bSml29623 				bad_config = B_TRUE;
6796f45ec7bSml29623 				break;
6806f45ec7bSml29623 			}
6816f45ec7bSml29623 			num_rdc += custom_num_rdc[port];
6826f45ec7bSml29623 			if (num_rdc > NXGE_MAX_RDCS) {
6836f45ec7bSml29623 				bad_config = B_TRUE;
6846f45ec7bSml29623 				break;
6856f45ec7bSml29623 			}
6866f45ec7bSml29623 			rdc_bitmap[port] = 0;
6876f45ec7bSml29623 			for (bits = 0;
6886f45ec7bSml29623 			    bits < custom_num_rdc[port]; bits++) {
6896f45ec7bSml29623 				rdc_bitmap[port] |=
6906f45ec7bSml29623 				    (1 << (bits + custom_start_rdc[port]));
6916f45ec7bSml29623 			}
6926f45ec7bSml29623 		}
6936f45ec7bSml29623 
6946f45ec7bSml29623 		if (bad_config == B_FALSE) {
6956f45ec7bSml29623 			/* check for overlap */
6966f45ec7bSml29623 			for (port = 0; port < num_ports - 1; port++) {
6976f45ec7bSml29623 				for (j = port + 1; j < num_ports; j++) {
6986f45ec7bSml29623 					if (rdc_bitmap[port] &
6996f45ec7bSml29623 					    rdc_bitmap[j]) {
7006f45ec7bSml29623 						NXGE_DEBUG_MSG((nxgep,
7016f45ec7bSml29623 						    CFG_CTL,
7026f45ec7bSml29623 						    " rxdma-cfg"
7036f45ec7bSml29623 						    " property custom"
7046f45ec7bSml29623 						    " bit overlap"
7056f45ec7bSml29623 						    " %d %d ",
7066f45ec7bSml29623 						    port, j));
7076f45ec7bSml29623 						bad_config = B_TRUE;
7086f45ec7bSml29623 						break;
7096f45ec7bSml29623 					}
7106f45ec7bSml29623 				}
7116f45ec7bSml29623 				if (bad_config == B_TRUE)
7126f45ec7bSml29623 					break;
7136f45ec7bSml29623 			}
7146f45ec7bSml29623 		}
7156f45ec7bSml29623 		if (bad_config == B_TRUE) {
7166f45ec7bSml29623 			/* use default config */
7176f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
7186f45ec7bSml29623 			    " rxdma-cfg property:"
7196f45ec7bSml29623 			    " bad custom config:"
7206f45ec7bSml29623 			    " use default"));
7216f45ec7bSml29623 			for (port = 0; port < num_ports; port++) {
7226f45ec7bSml29623 				custom_num_rdc[port] =
7236f45ec7bSml29623 				    (num_ports == 4) ?
7246f45ec7bSml29623 				    p4_rx_fair[port] :
7256f45ec7bSml29623 				    p2_rx_fair[port];
7266f45ec7bSml29623 				custom_start_rdc[port] = start_rdc;
7276f45ec7bSml29623 				start_rdc += custom_num_rdc[port];
7286f45ec7bSml29623 			}
7296f45ec7bSml29623 		}
7306f45ec7bSml29623 		break;
7316f45ec7bSml29623 
7326f45ec7bSml29623 	default:
7336f45ec7bSml29623 		/* use default config */
7346f45ec7bSml29623 		cfg_prop = "fair";
7356f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
7366f45ec7bSml29623 			custom_num_rdc[port] = (num_ports == 4) ?
7376f45ec7bSml29623 			    p4_rx_fair[port] : p2_rx_fair[port];
7386f45ec7bSml29623 			custom_start_rdc[port] = start_rdc;
7396f45ec7bSml29623 			start_rdc += custom_num_rdc[port];
7406f45ec7bSml29623 		}
7416f45ec7bSml29623 		break;
7426f45ec7bSml29623 	}
7436f45ec7bSml29623 
7446f45ec7bSml29623 	/* Now Update the rx properties */
7456f45ec7bSml29623 	for (port = 0; port < num_ports; port++) {
7466f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
7476f45ec7bSml29623 		    " update property rxdma-cfg with %s ", cfg_prop));
7486f45ec7bSml29623 		ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port],
7496f45ec7bSml29623 		    "rxdma-cfg", cfg_prop);
7506f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
7516f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
7526f45ec7bSml29623 			    " property rxdma-cfg is not updating to %s",
7536f45ec7bSml29623 			    cfg_prop));
7546f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
7556f45ec7bSml29623 		}
7566f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
7576f45ec7bSml29623 		    num_rdc_prop, custom_num_rdc[port]));
7586f45ec7bSml29623 
7596f45ec7bSml29623 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
7606f45ec7bSml29623 		    num_rdc_prop, custom_num_rdc[port]);
7616f45ec7bSml29623 
7626f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
7636f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7646f45ec7bSml29623 			    " property %s not updating with %d",
7656f45ec7bSml29623 			    num_rdc_prop, custom_num_rdc[port]));
7666f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
7676f45ec7bSml29623 		}
7686f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
7696f45ec7bSml29623 		    start_rdc_prop, custom_start_rdc[port]));
7706f45ec7bSml29623 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
7716f45ec7bSml29623 		    start_rdc_prop, custom_start_rdc[port]);
7726f45ec7bSml29623 
7736f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
7746f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
7756f45ec7bSml29623 			    " property %s not updating with %d ",
7766f45ec7bSml29623 			    start_rdc_prop, custom_start_rdc[port]));
7776f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
7786f45ec7bSml29623 		}
7796f45ec7bSml29623 	}
7806f45ec7bSml29623 	if (status & NXGE_DDI_FAILED)
7816f45ec7bSml29623 		status |= NXGE_ERROR;
7826f45ec7bSml29623 	return (status);
7836f45ec7bSml29623 }
7846f45ec7bSml29623 
7856f45ec7bSml29623 static nxge_status_t
7866f45ec7bSml29623 nxge_update_txdma_properties(p_nxge_t nxgep, config_token_t token,
7876f45ec7bSml29623 	dev_info_t *s_dip[])
7886f45ec7bSml29623 {
7896f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
7906f45ec7bSml29623 	int ddi_status = DDI_SUCCESS;
7916f45ec7bSml29623 	int num_ports = nxgep->nports;
7926f45ec7bSml29623 	int port, bits, j;
793da14cebeSEric Cheng 	uint8_t  start_tdc, num_tdc = 0;
7946f45ec7bSml29623 	p_nxge_param_t param_arr;
7956f45ec7bSml29623 	uint32_t tdc_bitmap[MAX_SIBLINGS];
7966f45ec7bSml29623 	int custom_start_tdc[MAX_SIBLINGS];
7976f45ec7bSml29623 	int custom_num_tdc[MAX_SIBLINGS];
7986f45ec7bSml29623 	uint8_t bad_config = B_FALSE;
7996f45ec7bSml29623 	int *prop_val;
8006f45ec7bSml29623 	uint_t prop_len;
8016f45ec7bSml29623 	char *start_tdc_prop, *num_tdc_prop, *cfg_prop;
8026f45ec7bSml29623 
8036f45ec7bSml29623 	start_tdc = 0;
8046f45ec7bSml29623 	param_arr = nxgep->param_arr;
8056f45ec7bSml29623 	start_tdc_prop = param_arr[param_txdma_channels_begin].fcode_name;
8066f45ec7bSml29623 	num_tdc_prop = param_arr[param_txdma_channels].fcode_name;
8076f45ec7bSml29623 
8086f45ec7bSml29623 	switch (token) {
8096f45ec7bSml29623 	case FAIR:
8106f45ec7bSml29623 		cfg_prop = "fair";
8116f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
8126f45ec7bSml29623 			custom_num_tdc[port] = (num_ports == 4) ?
8136f45ec7bSml29623 			    p4_tx_fair[port] : p2_tx_fair[port];
8146f45ec7bSml29623 			custom_start_tdc[port] = start_tdc;
8156f45ec7bSml29623 			start_tdc += custom_num_tdc[port];
8166f45ec7bSml29623 		}
8176f45ec7bSml29623 		break;
8186f45ec7bSml29623 
8196f45ec7bSml29623 	case EQUAL:
8206f45ec7bSml29623 		cfg_prop = "equal";
8216f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
8226f45ec7bSml29623 			custom_num_tdc[port] = (num_ports == 4) ?
8236f45ec7bSml29623 			    p4_tx_equal[port] : p2_tx_equal[port];
8246f45ec7bSml29623 			custom_start_tdc[port] = start_tdc;
8256f45ec7bSml29623 			start_tdc += custom_num_tdc[port];
8266f45ec7bSml29623 		}
8276f45ec7bSml29623 		break;
8286f45ec7bSml29623 
8296f45ec7bSml29623 	case CUSTOM:
8306f45ec7bSml29623 		cfg_prop = "custom";
8316f45ec7bSml29623 		/* See if it is good config */
8326f45ec7bSml29623 		num_tdc = 0;
8336f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
8346f45ec7bSml29623 			ddi_status = ddi_prop_lookup_int_array(
8356f45ec7bSml29623 			    DDI_DEV_T_ANY, s_dip[port], 0, start_tdc_prop,
8366f45ec7bSml29623 			    &prop_val, &prop_len);
8376f45ec7bSml29623 			if (ddi_status == DDI_SUCCESS)
8386f45ec7bSml29623 				custom_start_tdc[port] = *prop_val;
8396f45ec7bSml29623 			else {
8406f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
8416f45ec7bSml29623 				    " %s custom start port %d"
8426f45ec7bSml29623 				    " read failed ", " txdma-cfg", port));
8436f45ec7bSml29623 				bad_config = B_TRUE;
8446f45ec7bSml29623 				status |= NXGE_DDI_FAILED;
8456f45ec7bSml29623 			}
8466f45ec7bSml29623 
8476f45ec7bSml29623 			if ((custom_start_tdc[port] == -1) ||
8486f45ec7bSml29623 			    (custom_start_tdc[port] >=
8496f45ec7bSml29623 			    NXGE_MAX_RDCS)) {
8506f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
8516f45ec7bSml29623 				    " %s custom start %d"
8526f45ec7bSml29623 				    " out of range %x ", " txdma-cfg",
8536f45ec7bSml29623 				    port, custom_start_tdc[port]));
8546f45ec7bSml29623 				bad_config = B_TRUE;
8556f45ec7bSml29623 				break;
8566f45ec7bSml29623 			}
8576f45ec7bSml29623 
8586f45ec7bSml29623 			ddi_status = ddi_prop_lookup_int_array(
8596f45ec7bSml29623 			    DDI_DEV_T_ANY, s_dip[port], 0, num_tdc_prop,
8606f45ec7bSml29623 			    &prop_val, &prop_len);
8616f45ec7bSml29623 			if (ddi_status == DDI_SUCCESS)
8626f45ec7bSml29623 				custom_num_tdc[port] = *prop_val;
8636f45ec7bSml29623 			else {
8646f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
8656f45ec7bSml29623 				    " %s custom num port %d"
8666f45ec7bSml29623 				    " read failed ", " txdma-cfg", port));
8676f45ec7bSml29623 				bad_config = B_TRUE;
8686f45ec7bSml29623 				status |= NXGE_DDI_FAILED;
8696f45ec7bSml29623 			}
8706f45ec7bSml29623 
8716f45ec7bSml29623 			if ((custom_num_tdc[port] == -1) ||
8726f45ec7bSml29623 			    (custom_num_tdc[port] >
8736f45ec7bSml29623 			    NXGE_MAX_TDCS) ||
8746f45ec7bSml29623 			    ((custom_num_tdc[port] +
8756f45ec7bSml29623 			    custom_start_tdc[port]) >
8766f45ec7bSml29623 			    NXGE_MAX_TDCS)) {
8776f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
8786f45ec7bSml29623 				    " %s custom num %d"
8796f45ec7bSml29623 				    " out of range %x ", " rxdma-cfg",
8806f45ec7bSml29623 				    port, custom_num_tdc[port]));
8816f45ec7bSml29623 				bad_config = B_TRUE;
8826f45ec7bSml29623 				break;
8836f45ec7bSml29623 			}
8846f45ec7bSml29623 			num_tdc += custom_num_tdc[port];
8856f45ec7bSml29623 			if (num_tdc > NXGE_MAX_TDCS) {
8866f45ec7bSml29623 				bad_config = B_TRUE;
8876f45ec7bSml29623 				break;
8886f45ec7bSml29623 			}
8896f45ec7bSml29623 			tdc_bitmap[port] = 0;
8906f45ec7bSml29623 			for (bits = 0;
8916f45ec7bSml29623 			    bits < custom_num_tdc[port]; bits++) {
8926f45ec7bSml29623 				tdc_bitmap[port] |=
8936f45ec7bSml29623 				    (1 <<
8946f45ec7bSml29623 				    (bits + custom_start_tdc[port]));
8956f45ec7bSml29623 			}
8966f45ec7bSml29623 
8976f45ec7bSml29623 		}
8986f45ec7bSml29623 
8996f45ec7bSml29623 		if (bad_config == B_FALSE) {
9006f45ec7bSml29623 			/* check for overlap */
9016f45ec7bSml29623 			for (port = 0; port < num_ports - 1; port++) {
9026f45ec7bSml29623 				for (j = port + 1; j < num_ports; j++) {
9036f45ec7bSml29623 					if (tdc_bitmap[port] &
9046f45ec7bSml29623 					    tdc_bitmap[j]) {
9056f45ec7bSml29623 						NXGE_DEBUG_MSG((nxgep, CFG_CTL,
9066f45ec7bSml29623 						    " rxdma-cfg"
9076f45ec7bSml29623 						    " property custom"
9086f45ec7bSml29623 						    " bit overlap"
9096f45ec7bSml29623 						    " %d %d ",
9106f45ec7bSml29623 						    port, j));
9116f45ec7bSml29623 						bad_config = B_TRUE;
9126f45ec7bSml29623 						break;
9136f45ec7bSml29623 					}
9146f45ec7bSml29623 				}
9156f45ec7bSml29623 				if (bad_config == B_TRUE)
9166f45ec7bSml29623 					break;
9176f45ec7bSml29623 			}
9186f45ec7bSml29623 		}
9196f45ec7bSml29623 		if (bad_config == B_TRUE) {
9206f45ec7bSml29623 			/* use default config */
9216f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
9226f45ec7bSml29623 			    " txdma-cfg property:"
9236f45ec7bSml29623 			    " bad custom config:" " use default"));
9246f45ec7bSml29623 
9256f45ec7bSml29623 			for (port = 0; port < num_ports; port++) {
9266f45ec7bSml29623 				custom_num_tdc[port] = (num_ports == 4) ?
9276f45ec7bSml29623 				    p4_tx_fair[port] : p2_tx_fair[port];
9286f45ec7bSml29623 				custom_start_tdc[port] = start_tdc;
9296f45ec7bSml29623 				start_tdc += custom_num_tdc[port];
9306f45ec7bSml29623 			}
9316f45ec7bSml29623 		}
9326f45ec7bSml29623 		break;
9336f45ec7bSml29623 
9346f45ec7bSml29623 	default:
9356f45ec7bSml29623 		/* use default config */
9366f45ec7bSml29623 		cfg_prop = "fair";
9376f45ec7bSml29623 		for (port = 0; port < num_ports; port++) {
9386f45ec7bSml29623 			custom_num_tdc[port] = (num_ports == 4) ?
9396f45ec7bSml29623 			    p4_tx_fair[port] : p2_tx_fair[port];
9406f45ec7bSml29623 			custom_start_tdc[port] = start_tdc;
9416f45ec7bSml29623 			start_tdc += custom_num_tdc[port];
9426f45ec7bSml29623 		}
9436f45ec7bSml29623 		break;
9446f45ec7bSml29623 	}
9456f45ec7bSml29623 
9466f45ec7bSml29623 	/* Now Update the tx properties */
9476f45ec7bSml29623 	for (port = 0; port < num_ports; port++) {
9486f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
9496f45ec7bSml29623 		    " update property txdma-cfg with %s ", cfg_prop));
9506f45ec7bSml29623 		ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port],
9516f45ec7bSml29623 		    "txdma-cfg", cfg_prop);
9526f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
9536f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
9546f45ec7bSml29623 			    " property txdma-cfg is not updating to %s",
9556f45ec7bSml29623 			    cfg_prop));
9566f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
9576f45ec7bSml29623 		}
9586f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
9596f45ec7bSml29623 		    num_tdc_prop, custom_num_tdc[port]));
9606f45ec7bSml29623 
9616f45ec7bSml29623 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
9626f45ec7bSml29623 		    num_tdc_prop, custom_num_tdc[port]);
9636f45ec7bSml29623 
9646f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
9656f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
9666f45ec7bSml29623 			    " property %s not updating with %d",
9676f45ec7bSml29623 			    num_tdc_prop,
9686f45ec7bSml29623 			    custom_num_tdc[port]));
9696f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
9706f45ec7bSml29623 		}
9716f45ec7bSml29623 
9726f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
9736f45ec7bSml29623 		    start_tdc_prop, custom_start_tdc[port]));
9746f45ec7bSml29623 
9756f45ec7bSml29623 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
9766f45ec7bSml29623 		    start_tdc_prop, custom_start_tdc[port]);
9776f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS) {
9786f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
9796f45ec7bSml29623 			    " property %s not updating with %d ",
9806f45ec7bSml29623 			    start_tdc_prop, custom_start_tdc[port]));
9816f45ec7bSml29623 			status |= NXGE_DDI_FAILED;
9826f45ec7bSml29623 		}
9836f45ec7bSml29623 	}
9846f45ec7bSml29623 	if (status & NXGE_DDI_FAILED)
9856f45ec7bSml29623 		status |= NXGE_ERROR;
9866f45ec7bSml29623 	return (status);
9876f45ec7bSml29623 }
9886f45ec7bSml29623 
9896f45ec7bSml29623 static nxge_status_t
9906f45ec7bSml29623 nxge_update_cfg_properties(p_nxge_t nxgep, uint32_t flags,
9916f45ec7bSml29623 	config_token_t token, dev_info_t *s_dip[])
9926f45ec7bSml29623 {
9936f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
9946f45ec7bSml29623 
9956f45ec7bSml29623 	switch (flags) {
9966f45ec7bSml29623 	case COMMON_TXDMA_CFG:
9976f45ec7bSml29623 		if (nxge_dma_obp_props_only == 0)
9986f45ec7bSml29623 			status = nxge_update_txdma_properties(nxgep,
9996f45ec7bSml29623 			    token, s_dip);
10006f45ec7bSml29623 		break;
10016f45ec7bSml29623 	case COMMON_RXDMA_CFG:
10026f45ec7bSml29623 		if (nxge_dma_obp_props_only == 0)
10036f45ec7bSml29623 			status = nxge_update_rxdma_properties(nxgep,
10046f45ec7bSml29623 			    token, s_dip);
10056f45ec7bSml29623 
10066f45ec7bSml29623 		break;
10076f45ec7bSml29623 	case COMMON_RXDMA_GRP_CFG:
10086f45ec7bSml29623 		status = nxge_update_rxdma_grp_properties(nxgep,
10096f45ec7bSml29623 		    token, s_dip);
10106f45ec7bSml29623 		break;
10116f45ec7bSml29623 	default:
10126f45ec7bSml29623 		return (NXGE_ERROR);
10136f45ec7bSml29623 	}
10146f45ec7bSml29623 	return (status);
10156f45ec7bSml29623 }
10166f45ec7bSml29623 
10176f45ec7bSml29623 /*
10186f45ec7bSml29623  * verify consistence.
10196f45ec7bSml29623  * (May require publishing the properties on all the ports.
10206f45ec7bSml29623  *
10216f45ec7bSml29623  * What if properties are published on function 0 device only?
10226f45ec7bSml29623  *
10236f45ec7bSml29623  *
10246f45ec7bSml29623  * rxdma-cfg, txdma-cfg, rxdma-grp-cfg (required )
10256f45ec7bSml29623  * What about class configs?
10266f45ec7bSml29623  *
10276f45ec7bSml29623  * If consistent, update the property on all the siblings.
10286f45ec7bSml29623  * set  a flag on hardware shared register
10296f45ec7bSml29623  * The rest of the siblings will check the flag
10306f45ec7bSml29623  * if the flag is set, they will use the updated property
10316f45ec7bSml29623  * without doing any validation.
10326f45ec7bSml29623  */
10336f45ec7bSml29623 
10346f45ec7bSml29623 nxge_status_t
10356f45ec7bSml29623 nxge_cfg_verify_set_classify_prop(p_nxge_t nxgep, char *prop,
10366f45ec7bSml29623 	uint64_t known_cfg, uint32_t override, dev_info_t *c_dip[])
10376f45ec7bSml29623 {
10386f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
10396f45ec7bSml29623 	int ddi_status = DDI_SUCCESS;
10406f45ec7bSml29623 	int i = 0, found = 0, update_prop = B_TRUE;
10416f45ec7bSml29623 	int *cfg_val;
10426f45ec7bSml29623 	uint_t new_value, cfg_value[MAX_SIBLINGS];
10436f45ec7bSml29623 	uint_t prop_len;
10446f45ec7bSml29623 	uint_t known_cfg_value;
10456f45ec7bSml29623 
10466f45ec7bSml29623 	known_cfg_value = (uint_t)known_cfg;
10476f45ec7bSml29623 
10486f45ec7bSml29623 	if (override == B_TRUE) {
10496f45ec7bSml29623 		new_value = known_cfg_value;
10506f45ec7bSml29623 		for (i = 0; i < nxgep->nports; i++) {
10516f45ec7bSml29623 			ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE,
10526f45ec7bSml29623 			    c_dip[i], prop, new_value);
10536f45ec7bSml29623 #ifdef NXGE_DEBUG_ERROR
10546f45ec7bSml29623 			if (ddi_status != DDI_PROP_SUCCESS)
10556f45ec7bSml29623 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
10566f45ec7bSml29623 				    " property %s failed update ", prop));
10576f45ec7bSml29623 #endif
10586f45ec7bSml29623 		}
10596f45ec7bSml29623 		if (ddi_status != DDI_PROP_SUCCESS)
10606f45ec7bSml29623 			return (NXGE_ERROR | NXGE_DDI_FAILED);
10616f45ec7bSml29623 	}
10626f45ec7bSml29623 	for (i = 0; i < nxgep->nports; i++) {
10636f45ec7bSml29623 		cfg_value[i] = known_cfg_value;
10646f45ec7bSml29623 		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, c_dip[i], 0,
10656f45ec7bSml29623 		    prop, &cfg_val,
10666f45ec7bSml29623 		    &prop_len) == DDI_PROP_SUCCESS) {
10676f45ec7bSml29623 			cfg_value[i] = *cfg_val;
10686f45ec7bSml29623 			ddi_prop_free(cfg_val);
10696f45ec7bSml29623 			found++;
10706f45ec7bSml29623 		}
10716f45ec7bSml29623 	}
10726f45ec7bSml29623 
10736f45ec7bSml29623 	if (found != i) {
10746f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
10756f45ec7bSml29623 		    " property %s not specified on all ports", prop));
10766f45ec7bSml29623 		if (found == 0) {
10776f45ec7bSml29623 			/* not specified: Use default */
10786f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
10796f45ec7bSml29623 			    " property %s not specified on any port:"
10806f45ec7bSml29623 			    " Using default", prop));
10816f45ec7bSml29623 			new_value = known_cfg_value;
10826f45ec7bSml29623 		} else {
10836f45ec7bSml29623 			/* specified on some */
10846f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
10856f45ec7bSml29623 			    " property %s not specified"
10866f45ec7bSml29623 			    " on some ports: Using default", prop));
10876f45ec7bSml29623 			/* ? use p0 value instead ? */
10886f45ec7bSml29623 			new_value = known_cfg_value;
10896f45ec7bSml29623 		}
10906f45ec7bSml29623 	} else {
10916f45ec7bSml29623 		/* check type and consistence */
10926f45ec7bSml29623 		/* found on all devices */
10936f45ec7bSml29623 		for (i = 1; i < found; i++) {
10946f45ec7bSml29623 			if (cfg_value[i] != cfg_value[i - 1]) {
10956f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
10966f45ec7bSml29623 				    " property %s inconsistent:"
10976f45ec7bSml29623 				    " Using default", prop));
10986f45ec7bSml29623 				new_value = known_cfg_value;
10996f45ec7bSml29623 				break;
11006f45ec7bSml29623 			}
11016f45ec7bSml29623 			/*
11026f45ec7bSml29623 			 * Found on all the ports and consistent. Nothing to
11036f45ec7bSml29623 			 * do.
11046f45ec7bSml29623 			 */
11056f45ec7bSml29623 			update_prop = B_FALSE;
11066f45ec7bSml29623 		}
11076f45ec7bSml29623 	}
11086f45ec7bSml29623 
11096f45ec7bSml29623 	if (update_prop == B_TRUE) {
11106f45ec7bSml29623 		for (i = 0; i < nxgep->nports; i++) {
11116f45ec7bSml29623 			ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE,
11126f45ec7bSml29623 			    c_dip[i], prop, new_value);
11136f45ec7bSml29623 #ifdef NXGE_DEBUG_ERROR
11146f45ec7bSml29623 			if (ddi_status != DDI_SUCCESS)
11156f45ec7bSml29623 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
11166f45ec7bSml29623 				    " property %s not updating with %d"
11176f45ec7bSml29623 				    " Using default",
11186f45ec7bSml29623 				    prop, new_value));
11196f45ec7bSml29623 #endif
11206f45ec7bSml29623 			if (ddi_status != DDI_PROP_SUCCESS)
11216f45ec7bSml29623 				status |= NXGE_DDI_FAILED;
11226f45ec7bSml29623 		}
11236f45ec7bSml29623 	}
11246f45ec7bSml29623 	if (status & NXGE_DDI_FAILED)
11256f45ec7bSml29623 		status |= NXGE_ERROR;
11266f45ec7bSml29623 
11276f45ec7bSml29623 	return (status);
11286f45ec7bSml29623 }
11296f45ec7bSml29623 
11306f45ec7bSml29623 static uint64_t
11316f45ec7bSml29623 nxge_class_get_known_cfg(p_nxge_t nxgep, int class_prop, int rx_quick_cfg)
11326f45ec7bSml29623 {
11336f45ec7bSml29623 	int start_prop;
11346f45ec7bSml29623 	uint64_t cfg_value;
11356f45ec7bSml29623 	p_nxge_param_t param_arr;
11366f45ec7bSml29623 
11376f45ec7bSml29623 	param_arr = nxgep->param_arr;
11386f45ec7bSml29623 	cfg_value = param_arr[class_prop].value;
11396f45ec7bSml29623 	start_prop = param_h1_init_value;
11406f45ec7bSml29623 
11416f45ec7bSml29623 	/* update the properties per quick config */
11426f45ec7bSml29623 	switch (rx_quick_cfg) {
11436f45ec7bSml29623 	case CFG_L3_WEB:
11446f45ec7bSml29623 	case CFG_L3_DISTRIBUTE:
11456f45ec7bSml29623 		cfg_value = nxge_classify_get_cfg_value(nxgep,
11466f45ec7bSml29623 		    rx_quick_cfg, class_prop - start_prop);
11476f45ec7bSml29623 		break;
11486f45ec7bSml29623 	default:
11496f45ec7bSml29623 		cfg_value = param_arr[class_prop].value;
11506f45ec7bSml29623 		break;
11516f45ec7bSml29623 	}
11526f45ec7bSml29623 	return (cfg_value);
11536f45ec7bSml29623 }
11546f45ec7bSml29623 
11556f45ec7bSml29623 static nxge_status_t
11566f45ec7bSml29623 nxge_cfg_verify_set_classify(p_nxge_t nxgep, dev_info_t *c_dip[])
11576f45ec7bSml29623 {
11586f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
11596f45ec7bSml29623 	int rx_quick_cfg, class_prop, start_prop, end_prop;
11606f45ec7bSml29623 	char *prop_name;
11616f45ec7bSml29623 	int override = B_TRUE;
11626f45ec7bSml29623 	uint64_t cfg_value;
11636f45ec7bSml29623 	p_nxge_param_t param_arr;
11646f45ec7bSml29623 
11656f45ec7bSml29623 	param_arr = nxgep->param_arr;
11666f45ec7bSml29623 	rx_quick_cfg = param_arr[param_rx_quick_cfg].value;
11676f45ec7bSml29623 	start_prop = param_h1_init_value;
11686f45ec7bSml29623 	end_prop = param_class_opt_ipv6_sctp;
11696f45ec7bSml29623 
11706f45ec7bSml29623 	/* update the properties per quick config */
11716f45ec7bSml29623 	if (rx_quick_cfg == CFG_NOT_SPECIFIED)
11726f45ec7bSml29623 		override = B_FALSE;
11736f45ec7bSml29623 
11746f45ec7bSml29623 	/*
11756f45ec7bSml29623 	 * these parameter affect the classification outcome.
11766f45ec7bSml29623 	 * these parameters are used to configure the Flow key and
11776f45ec7bSml29623 	 * the TCAM key for each of the IP classes.
11786f45ec7bSml29623 	 * Included here are also the H1 and H2 initial values
11796f45ec7bSml29623 	 * which affect the distribution as well as final hash value
11806f45ec7bSml29623 	 * (hence the offset into RDC table and FCRAM bucket location)
11816f45ec7bSml29623 	 *
11826f45ec7bSml29623 	 */
11836f45ec7bSml29623 	for (class_prop = start_prop; class_prop <= end_prop; class_prop++) {
11846f45ec7bSml29623 		prop_name = param_arr[class_prop].fcode_name;
11856f45ec7bSml29623 		cfg_value = nxge_class_get_known_cfg(nxgep,
11866f45ec7bSml29623 		    class_prop, rx_quick_cfg);
11876f45ec7bSml29623 		status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name,
11886f45ec7bSml29623 		    cfg_value, override, c_dip);
11896f45ec7bSml29623 	}
11906f45ec7bSml29623 
11916f45ec7bSml29623 	/*
11926f45ec7bSml29623 	 * these properties do not affect the actual classification outcome.
11936f45ec7bSml29623 	 * used to enable/disable or tune the fflp hardware
11946f45ec7bSml29623 	 *
11956f45ec7bSml29623 	 * fcram_access_ratio, tcam_access_ratio, tcam_enable, llc_snap_enable
11966f45ec7bSml29623 	 *
11976f45ec7bSml29623 	 */
11986f45ec7bSml29623 	override = B_FALSE;
11996f45ec7bSml29623 	for (class_prop = param_fcram_access_ratio;
12006f45ec7bSml29623 	    class_prop <= param_llc_snap_enable; class_prop++) {
12016f45ec7bSml29623 		prop_name = param_arr[class_prop].fcode_name;
12026f45ec7bSml29623 		cfg_value = param_arr[class_prop].value;
12036f45ec7bSml29623 		status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name,
12046f45ec7bSml29623 		    cfg_value, override, c_dip);
12056f45ec7bSml29623 	}
12066f45ec7bSml29623 
12076f45ec7bSml29623 	return (status);
12086f45ec7bSml29623 }
12096f45ec7bSml29623 
12106f45ec7bSml29623 nxge_status_t
12116f45ec7bSml29623 nxge_cfg_verify_set(p_nxge_t nxgep, uint32_t flag)
12126f45ec7bSml29623 {
12136f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
12146f45ec7bSml29623 	int i = 0, found = 0;
12156f45ec7bSml29623 	int num_siblings;
12166f45ec7bSml29623 	dev_info_t *c_dip[MAX_SIBLINGS + 1];
12176f45ec7bSml29623 	char *prop_val[MAX_SIBLINGS];
12186f45ec7bSml29623 	config_token_t c_token[MAX_SIBLINGS];
12196f45ec7bSml29623 	char *prop;
12206f45ec7bSml29623 
12216f45ec7bSml29623 	if (nxge_dma_obp_props_only)
12226f45ec7bSml29623 		return (NXGE_OK);
12236f45ec7bSml29623 
12246f45ec7bSml29623 	num_siblings = 0;
12256f45ec7bSml29623 	c_dip[num_siblings] = ddi_get_child(nxgep->p_dip);
12266f45ec7bSml29623 	while (c_dip[num_siblings]) {
12276f45ec7bSml29623 		c_dip[num_siblings + 1] =
12286f45ec7bSml29623 		    ddi_get_next_sibling(c_dip[num_siblings]);
12296f45ec7bSml29623 		num_siblings++;
12306f45ec7bSml29623 	}
12316f45ec7bSml29623 
12326f45ec7bSml29623 	switch (flag) {
12336f45ec7bSml29623 	case COMMON_TXDMA_CFG:
12346f45ec7bSml29623 		prop = "txdma-cfg";
12356f45ec7bSml29623 		break;
12366f45ec7bSml29623 	case COMMON_RXDMA_CFG:
12376f45ec7bSml29623 		prop = "rxdma-cfg";
12386f45ec7bSml29623 		break;
12396f45ec7bSml29623 	case COMMON_RXDMA_GRP_CFG:
12406f45ec7bSml29623 		prop = "rxdma-grp-cfg";
12416f45ec7bSml29623 		break;
12426f45ec7bSml29623 	case COMMON_CLASS_CFG:
12436f45ec7bSml29623 		status = nxge_cfg_verify_set_classify(nxgep, c_dip);
12446f45ec7bSml29623 		return (status);
12456f45ec7bSml29623 	default:
12466f45ec7bSml29623 		return (NXGE_ERROR);
12476f45ec7bSml29623 	}
12486f45ec7bSml29623 
12496f45ec7bSml29623 	i = 0;
12506f45ec7bSml29623 	while (i < num_siblings) {
12516f45ec7bSml29623 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, c_dip[i], 0, prop,
12526f45ec7bSml29623 		    (char **)&prop_val[i]) == DDI_PROP_SUCCESS) {
12536f45ec7bSml29623 			c_token[i] = nxge_get_config_token(prop_val[i]);
12546f45ec7bSml29623 			ddi_prop_free(prop_val[i]);
12556f45ec7bSml29623 			found++;
12566f45ec7bSml29623 		} else
12576f45ec7bSml29623 			c_token[i] = CONFIG_TOKEN_NONE;
12586f45ec7bSml29623 		i++;
12596f45ec7bSml29623 	}
12606f45ec7bSml29623 
12616f45ec7bSml29623 	if (found != i) {
12626f45ec7bSml29623 		if (found == 0) {
12636f45ec7bSml29623 			/* not specified: Use default */
12646f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
12656f45ec7bSml29623 			    " property %s not specified on any port:"
12666f45ec7bSml29623 			    " Using default", prop));
12676f45ec7bSml29623 
12686f45ec7bSml29623 			status = nxge_update_cfg_properties(nxgep,
12696f45ec7bSml29623 			    flag, FAIR, c_dip);
12706f45ec7bSml29623 			return (status);
12716f45ec7bSml29623 		} else {
12726f45ec7bSml29623 			/*
12736f45ec7bSml29623 			 * if  the convention is to use function 0 device then
12746f45ec7bSml29623 			 * populate the other devices with this configuration.
12756f45ec7bSml29623 			 *
12766f45ec7bSml29623 			 * The other alternative is to use the default config.
12776f45ec7bSml29623 			 */
12786f45ec7bSml29623 			/* not specified: Use default */
12796f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
12806f45ec7bSml29623 			    " property %s not specified on some ports:"
12816f45ec7bSml29623 			    " Using default", prop));
12826f45ec7bSml29623 			status = nxge_update_cfg_properties(nxgep,
12836f45ec7bSml29623 			    flag, FAIR, c_dip);
12846f45ec7bSml29623 			return (status);
12856f45ec7bSml29623 		}
12866f45ec7bSml29623 	}
12876f45ec7bSml29623 
12886f45ec7bSml29623 	/* check type and consistence */
12896f45ec7bSml29623 	/* found on all devices */
12906f45ec7bSml29623 	for (i = 1; i < found; i++) {
12916f45ec7bSml29623 		if (c_token[i] != c_token[i - 1]) {
12926f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
12936f45ec7bSml29623 			    " property %s inconsistent:"
12946f45ec7bSml29623 			    " Using default", prop));
12956f45ec7bSml29623 			status = nxge_update_cfg_properties(nxgep,
12966f45ec7bSml29623 			    flag, FAIR, c_dip);
12976f45ec7bSml29623 			return (status);
12986f45ec7bSml29623 		}
12996f45ec7bSml29623 	}
13006f45ec7bSml29623 
13016f45ec7bSml29623 	/*
13026f45ec7bSml29623 	 * Found on all the ports check if it is custom configuration. if
13036f45ec7bSml29623 	 * custom, then verify consistence
13046f45ec7bSml29623 	 *
13056f45ec7bSml29623 	 * finally create soft properties
13066f45ec7bSml29623 	 */
13076f45ec7bSml29623 	status = nxge_update_cfg_properties(nxgep, flag, c_token[0], c_dip);
13086f45ec7bSml29623 	return (status);
13096f45ec7bSml29623 }
13106f45ec7bSml29623 
13116f45ec7bSml29623 nxge_status_t
13126f45ec7bSml29623 nxge_cfg_verify_set_quick_config(p_nxge_t nxgep)
13136f45ec7bSml29623 {
13146f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
13156f45ec7bSml29623 	int ddi_status = DDI_SUCCESS;
13166f45ec7bSml29623 	char *prop_val;
13176f45ec7bSml29623 	char *rx_prop;
13186f45ec7bSml29623 	char *prop;
13196f45ec7bSml29623 	uint32_t cfg_value = CFG_NOT_SPECIFIED;
13206f45ec7bSml29623 	p_nxge_param_t param_arr;
13216f45ec7bSml29623 
13226f45ec7bSml29623 	param_arr = nxgep->param_arr;
13236f45ec7bSml29623 	rx_prop = param_arr[param_rx_quick_cfg].fcode_name;
13246f45ec7bSml29623 
13256f45ec7bSml29623 	prop = "rx-quick-cfg";
13266f45ec7bSml29623 
13276f45ec7bSml29623 	/*
13286f45ec7bSml29623 	 * good value are
13296f45ec7bSml29623 	 *
13306f45ec7bSml29623 	 * "web-server" "generic-server" "l3-classify" "flow-classify"
13316f45ec7bSml29623 	 */
13326f45ec7bSml29623 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
13336f45ec7bSml29623 	    prop, (char **)&prop_val) != DDI_PROP_SUCCESS) {
13346f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, VPD_CTL,
13356f45ec7bSml29623 		    " property %s not specified: using default ", prop));
13366f45ec7bSml29623 		cfg_value = CFG_NOT_SPECIFIED;
13376f45ec7bSml29623 	} else {
13386f45ec7bSml29623 		cfg_value = CFG_L3_DISTRIBUTE;
13396f45ec7bSml29623 		if (strncmp("web-server", (caddr_t)prop_val, 8) == 0) {
13406f45ec7bSml29623 			cfg_value = CFG_L3_WEB;
13416f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
13426f45ec7bSml29623 			    " %s: web server ", prop));
13436f45ec7bSml29623 		}
13446f45ec7bSml29623 		if (strncmp("generic-server", (caddr_t)prop_val, 8) == 0) {
13456f45ec7bSml29623 			cfg_value = CFG_L3_DISTRIBUTE;
13466f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
13476f45ec7bSml29623 			    " %s: distribute ", prop));
13486f45ec7bSml29623 		}
13496f45ec7bSml29623 		/* more */
13506f45ec7bSml29623 		ddi_prop_free(prop_val);
13516f45ec7bSml29623 	}
13526f45ec7bSml29623 
13536f45ec7bSml29623 	ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
13546f45ec7bSml29623 	    rx_prop, cfg_value);
13556f45ec7bSml29623 	if (ddi_status != DDI_PROP_SUCCESS)
13566f45ec7bSml29623 		status |= NXGE_DDI_FAILED;
13576f45ec7bSml29623 
13586f45ec7bSml29623 	/* now handle specified cases: */
13596f45ec7bSml29623 	if (status & NXGE_DDI_FAILED)
13606f45ec7bSml29623 		status |= NXGE_ERROR;
13616f45ec7bSml29623 	return (status);
13626f45ec7bSml29623 }
13636f45ec7bSml29623 
136400161856Syc148097 /*
136500161856Syc148097  * Device properties adv-autoneg-cap etc are defined by FWARC
136600161856Syc148097  * http://sac.sfbay/FWARC/2002/345/20020610_asif.haswarey
136700161856Syc148097  */
13686f45ec7bSml29623 static void
13696f45ec7bSml29623 nxge_use_cfg_link_cfg(p_nxge_t nxgep)
13706f45ec7bSml29623 {
13716f45ec7bSml29623 	int *prop_val;
13726f45ec7bSml29623 	uint_t prop_len;
13736f45ec7bSml29623 	dev_info_t *dip;
13746f45ec7bSml29623 	int speed;
13756f45ec7bSml29623 	int duplex;
13766f45ec7bSml29623 	int adv_autoneg_cap;
13776f45ec7bSml29623 	int adv_10gfdx_cap;
13786f45ec7bSml29623 	int adv_10ghdx_cap;
13796f45ec7bSml29623 	int adv_1000fdx_cap;
13806f45ec7bSml29623 	int adv_1000hdx_cap;
13816f45ec7bSml29623 	int adv_100fdx_cap;
13826f45ec7bSml29623 	int adv_100hdx_cap;
13836f45ec7bSml29623 	int adv_10fdx_cap;
13846f45ec7bSml29623 	int adv_10hdx_cap;
13856f45ec7bSml29623 	int status = DDI_SUCCESS;
13866f45ec7bSml29623 
13876f45ec7bSml29623 	dip = nxgep->dip;
13886f45ec7bSml29623 
13896f45ec7bSml29623 	/*
13906f45ec7bSml29623 	 * first find out the card type and the supported link speeds and
13916f45ec7bSml29623 	 * features
13926f45ec7bSml29623 	 */
13936f45ec7bSml29623 	/* add code for card type */
13946f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-autoneg-cap",
13956f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
13966f45ec7bSml29623 		ddi_prop_free(prop_val);
13976f45ec7bSml29623 		return;
13986f45ec7bSml29623 	}
13996f45ec7bSml29623 
14006f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10gfdx-cap",
14016f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14026f45ec7bSml29623 		ddi_prop_free(prop_val);
14036f45ec7bSml29623 		return;
14046f45ec7bSml29623 	}
14056f45ec7bSml29623 
14066f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000hdx-cap",
14076f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14086f45ec7bSml29623 		ddi_prop_free(prop_val);
14096f45ec7bSml29623 		return;
14106f45ec7bSml29623 	}
14116f45ec7bSml29623 
14126f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000fdx-cap",
14136f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14146f45ec7bSml29623 		ddi_prop_free(prop_val);
14156f45ec7bSml29623 		return;
14166f45ec7bSml29623 	}
14176f45ec7bSml29623 
14186f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100fdx-cap",
14196f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14206f45ec7bSml29623 		ddi_prop_free(prop_val);
14216f45ec7bSml29623 		return;
14226f45ec7bSml29623 	}
14236f45ec7bSml29623 
14246f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100hdx-cap",
14256f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14266f45ec7bSml29623 		ddi_prop_free(prop_val);
14276f45ec7bSml29623 		return;
14286f45ec7bSml29623 	}
14296f45ec7bSml29623 
14306f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10fdx-cap",
14316f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14326f45ec7bSml29623 		ddi_prop_free(prop_val);
14336f45ec7bSml29623 		return;
14346f45ec7bSml29623 	}
14356f45ec7bSml29623 
14366f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10hdx-cap",
14376f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14386f45ec7bSml29623 		ddi_prop_free(prop_val);
14396f45ec7bSml29623 		return;
14406f45ec7bSml29623 	}
14416f45ec7bSml29623 
14426f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "speed",
14436f45ec7bSml29623 	    (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14446f45ec7bSml29623 		if (strncmp("10000", (caddr_t)prop_val,
14456f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14466f45ec7bSml29623 			speed = 10000;
14476f45ec7bSml29623 		} else if (strncmp("1000", (caddr_t)prop_val,
14486f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14496f45ec7bSml29623 			speed = 1000;
14506f45ec7bSml29623 		} else if (strncmp("100", (caddr_t)prop_val,
14516f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14526f45ec7bSml29623 			speed = 100;
14536f45ec7bSml29623 		} else if (strncmp("10", (caddr_t)prop_val,
14546f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14556f45ec7bSml29623 			speed = 10;
14566f45ec7bSml29623 		} else if (strncmp("auto", (caddr_t)prop_val,
14576f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14586f45ec7bSml29623 			speed = 0;
14596f45ec7bSml29623 		} else {
14606f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_NOTE,
14616f45ec7bSml29623 			    "speed property is invalid reverting to auto"));
14626f45ec7bSml29623 			speed = 0;
14636f45ec7bSml29623 		}
14646f45ec7bSml29623 		ddi_prop_free(prop_val);
14656f45ec7bSml29623 	} else
14666f45ec7bSml29623 		speed = 0;
14676f45ec7bSml29623 
14686f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0, "duplex",
14696f45ec7bSml29623 	    (uchar_t **)&prop_val, &prop_len) == DDI_PROP_SUCCESS) {
14706f45ec7bSml29623 		if (strncmp("full", (caddr_t)prop_val,
14716f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14726f45ec7bSml29623 			duplex = 2;
14736f45ec7bSml29623 		} else if (strncmp("half", (caddr_t)prop_val,
14746f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14756f45ec7bSml29623 			duplex = 1;
14766f45ec7bSml29623 		} else if (strncmp("auto", (caddr_t)prop_val,
14776f45ec7bSml29623 		    (size_t)prop_len) == 0) {
14786f45ec7bSml29623 			duplex = 0;
14796f45ec7bSml29623 		} else {
14806f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_NOTE,
14816f45ec7bSml29623 			    "duplex property is invalid"
14826f45ec7bSml29623 			    " reverting to auto"));
14836f45ec7bSml29623 			duplex = 0;
14846f45ec7bSml29623 		}
14856f45ec7bSml29623 		ddi_prop_free(prop_val);
14866f45ec7bSml29623 	} else
14876f45ec7bSml29623 		duplex = 0;
14886f45ec7bSml29623 
148900161856Syc148097 	/* speed == 0 or duplex == 0 means auto negotiation. */
14906f45ec7bSml29623 	adv_autoneg_cap = (speed == 0) || (duplex == 0);
14916f45ec7bSml29623 	if (adv_autoneg_cap == 0) {
14926f45ec7bSml29623 		adv_10gfdx_cap = ((speed == 10000) && (duplex == 2));
14936f45ec7bSml29623 		adv_10ghdx_cap = adv_10gfdx_cap;
14946f45ec7bSml29623 		adv_10ghdx_cap |= ((speed == 10000) && (duplex == 1));
14956f45ec7bSml29623 		adv_1000fdx_cap = adv_10ghdx_cap;
14966f45ec7bSml29623 		adv_1000fdx_cap |= ((speed == 1000) && (duplex == 2));
14976f45ec7bSml29623 		adv_1000hdx_cap = adv_1000fdx_cap;
14986f45ec7bSml29623 		adv_1000hdx_cap |= ((speed == 1000) && (duplex == 1));
14996f45ec7bSml29623 		adv_100fdx_cap = adv_1000hdx_cap;
15006f45ec7bSml29623 		adv_100fdx_cap |= ((speed == 100) && (duplex == 2));
15016f45ec7bSml29623 		adv_100hdx_cap = adv_100fdx_cap;
15026f45ec7bSml29623 		adv_100hdx_cap |= ((speed == 100) && (duplex == 1));
15036f45ec7bSml29623 		adv_10fdx_cap = adv_100hdx_cap;
15046f45ec7bSml29623 		adv_10fdx_cap |= ((speed == 10) && (duplex == 2));
15056f45ec7bSml29623 		adv_10hdx_cap = adv_10fdx_cap;
15066f45ec7bSml29623 		adv_10hdx_cap |= ((speed == 10) && (duplex == 1));
15076f45ec7bSml29623 	} else if (speed == 0) {
15086f45ec7bSml29623 		adv_10gfdx_cap = (duplex == 2);
15096f45ec7bSml29623 		adv_10ghdx_cap = (duplex == 1);
15106f45ec7bSml29623 		adv_1000fdx_cap = (duplex == 2);
15116f45ec7bSml29623 		adv_1000hdx_cap = (duplex == 1);
15126f45ec7bSml29623 		adv_100fdx_cap = (duplex == 2);
15136f45ec7bSml29623 		adv_100hdx_cap = (duplex == 1);
15146f45ec7bSml29623 		adv_10fdx_cap = (duplex == 2);
15156f45ec7bSml29623 		adv_10hdx_cap = (duplex == 1);
15166f45ec7bSml29623 	}
15176f45ec7bSml29623 	if (duplex == 0) {
15186f45ec7bSml29623 		adv_10gfdx_cap = (speed == 0);
15196f45ec7bSml29623 		adv_10gfdx_cap |= (speed == 10000);
15206f45ec7bSml29623 		adv_10ghdx_cap = adv_10gfdx_cap;
15216f45ec7bSml29623 		adv_10ghdx_cap |= (speed == 10000);
15226f45ec7bSml29623 		adv_1000fdx_cap = adv_10ghdx_cap;
15236f45ec7bSml29623 		adv_1000fdx_cap |= (speed == 1000);
15246f45ec7bSml29623 		adv_1000hdx_cap = adv_1000fdx_cap;
15256f45ec7bSml29623 		adv_1000hdx_cap |= (speed == 1000);
15266f45ec7bSml29623 		adv_100fdx_cap = adv_1000hdx_cap;
15276f45ec7bSml29623 		adv_100fdx_cap |= (speed == 100);
15286f45ec7bSml29623 		adv_100hdx_cap = adv_100fdx_cap;
15296f45ec7bSml29623 		adv_100hdx_cap |= (speed == 100);
15306f45ec7bSml29623 		adv_10fdx_cap = adv_100hdx_cap;
15316f45ec7bSml29623 		adv_10fdx_cap |= (speed == 10);
15326f45ec7bSml29623 		adv_10hdx_cap = adv_10fdx_cap;
15336f45ec7bSml29623 		adv_10hdx_cap |= (speed == 10);
15346f45ec7bSml29623 	}
15356f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15366f45ec7bSml29623 	    "adv-autoneg-cap", &adv_autoneg_cap, 1);
15376f45ec7bSml29623 	if (status)
15386f45ec7bSml29623 		return;
15396f45ec7bSml29623 
15406f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15416f45ec7bSml29623 	    "adv-10gfdx-cap", &adv_10gfdx_cap, 1);
15426f45ec7bSml29623 	if (status)
15436f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail1;
15446f45ec7bSml29623 
15456f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15466f45ec7bSml29623 	    "adv-10ghdx-cap", &adv_10ghdx_cap, 1);
15476f45ec7bSml29623 	if (status)
15486f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail2;
15496f45ec7bSml29623 
15506f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15516f45ec7bSml29623 	    "adv-1000fdx-cap", &adv_1000fdx_cap, 1);
15526f45ec7bSml29623 	if (status)
15536f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail3;
15546f45ec7bSml29623 
15556f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15566f45ec7bSml29623 	    "adv-1000hdx-cap", &adv_1000hdx_cap, 1);
15576f45ec7bSml29623 	if (status)
15586f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail4;
15596f45ec7bSml29623 
15606f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15616f45ec7bSml29623 	    "adv-100fdx-cap", &adv_100fdx_cap, 1);
15626f45ec7bSml29623 	if (status)
15636f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail5;
15646f45ec7bSml29623 
15656f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15666f45ec7bSml29623 	    "adv-100hdx-cap", &adv_100hdx_cap, 1);
15676f45ec7bSml29623 	if (status)
15686f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail6;
15696f45ec7bSml29623 
15706f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15716f45ec7bSml29623 	    "adv-10fdx-cap", &adv_10fdx_cap, 1);
15726f45ec7bSml29623 	if (status)
15736f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail7;
15746f45ec7bSml29623 
15756f45ec7bSml29623 	status = ddi_prop_update_int_array(DDI_DEV_T_NONE, dip,
15766f45ec7bSml29623 	    "adv-10hdx-cap", &adv_10hdx_cap, 1);
15776f45ec7bSml29623 	if (status)
15786f45ec7bSml29623 		goto nxge_map_myargs_to_gmii_fail8;
15796f45ec7bSml29623 
15806f45ec7bSml29623 	return;
15816f45ec7bSml29623 
15826f45ec7bSml29623 nxge_map_myargs_to_gmii_fail9:
15836f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10hdx-cap");
15846f45ec7bSml29623 
15856f45ec7bSml29623 nxge_map_myargs_to_gmii_fail8:
15866f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10fdx-cap");
15876f45ec7bSml29623 
15886f45ec7bSml29623 nxge_map_myargs_to_gmii_fail7:
15896f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100hdx-cap");
15906f45ec7bSml29623 
15916f45ec7bSml29623 nxge_map_myargs_to_gmii_fail6:
15926f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-100fdx-cap");
15936f45ec7bSml29623 
15946f45ec7bSml29623 nxge_map_myargs_to_gmii_fail5:
15956f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000hdx-cap");
15966f45ec7bSml29623 
15976f45ec7bSml29623 nxge_map_myargs_to_gmii_fail4:
15986f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-1000fdx-cap");
15996f45ec7bSml29623 
16006f45ec7bSml29623 nxge_map_myargs_to_gmii_fail3:
16016f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10ghdx-cap");
16026f45ec7bSml29623 
16036f45ec7bSml29623 nxge_map_myargs_to_gmii_fail2:
16046f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-10gfdx-cap");
16056f45ec7bSml29623 
16066f45ec7bSml29623 nxge_map_myargs_to_gmii_fail1:
16076f45ec7bSml29623 	(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "adv-autoneg-cap");
16086f45ec7bSml29623 }
16096f45ec7bSml29623 
16106f45ec7bSml29623 nxge_status_t
16116f45ec7bSml29623 nxge_get_config_properties(p_nxge_t nxgep)
16126f45ec7bSml29623 {
16136f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
16146f45ec7bSml29623 	p_nxge_hw_list_t hw_p;
16154df55fdeSJanie Lu 	char **prop_val;
16164df55fdeSJanie Lu 	uint_t prop_len;
16174df55fdeSJanie Lu 	uint_t i;
16186f45ec7bSml29623 
16196f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, VPD_CTL, " ==> nxge_get_config_properties"));
16206f45ec7bSml29623 
16216f45ec7bSml29623 	if ((hw_p = nxgep->nxge_hw_p) == NULL) {
16226f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
16236f45ec7bSml29623 		    " nxge_get_config_properties:"
16246f45ec7bSml29623 		    " common hardware not set", nxgep->niu_type));
16256f45ec7bSml29623 		return (NXGE_ERROR);
16266f45ec7bSml29623 	}
16276f45ec7bSml29623 
16286f45ec7bSml29623 	/*
16296f45ec7bSml29623 	 * Get info on how many ports Neptune card has.
16306f45ec7bSml29623 	 */
16312e59129aSraghus 	nxgep->nports = nxge_get_nports(nxgep);
163259ac0c16Sdavemq 	if (nxgep->nports <= 0) {
163356d930aeSspeer 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
163459ac0c16Sdavemq 		    "<==nxge_get_config_properties: Invalid Neptune type 0x%x",
163559ac0c16Sdavemq 		    nxgep->niu_type));
163659ac0c16Sdavemq 		return (NXGE_ERROR);
163756d930aeSspeer 	}
163859ac0c16Sdavemq 	nxgep->classifier.tcam_size = TCAM_NIU_TCAM_MAX_ENTRY;
16392e59129aSraghus 	if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
16402e59129aSraghus 		nxgep->classifier.tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY;
16412e59129aSraghus 	}
164259ac0c16Sdavemq 	if (nxgep->function_num >= nxgep->nports) {
164359ac0c16Sdavemq 		return (NXGE_ERROR);
16446f45ec7bSml29623 	}
16456f45ec7bSml29623 
16466f45ec7bSml29623 	status = nxge_get_mac_addr_properties(nxgep);
16476f45ec7bSml29623 	if (status != NXGE_OK)
16486f45ec7bSml29623 		return (NXGE_ERROR);
16496f45ec7bSml29623 
16506f45ec7bSml29623 	/*
16516f45ec7bSml29623 	 * read the configuration type. If none is specified, used default.
16526f45ec7bSml29623 	 * Config types: equal: (default) DMA channels, RDC groups, TCAM, FCRAM
16536f45ec7bSml29623 	 * are shared equally across all the ports.
16546f45ec7bSml29623 	 *
16556f45ec7bSml29623 	 * Fair: DMA channels, RDC groups, TCAM, FCRAM are shared proportional
16566f45ec7bSml29623 	 * to the port speed.
16576f45ec7bSml29623 	 *
16586f45ec7bSml29623 	 *
16596f45ec7bSml29623 	 * custom: DMA channels, RDC groups, TCAM, FCRAM partition is
16606f45ec7bSml29623 	 * specified in nxge.conf. Need to read each parameter and set
16616f45ec7bSml29623 	 * up the parameters in nxge structures.
16626f45ec7bSml29623 	 *
16636f45ec7bSml29623 	 */
16646f45ec7bSml29623 	switch (nxgep->niu_type) {
16656f45ec7bSml29623 	case N2_NIU:
16666f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, VPD_CTL,
16676f45ec7bSml29623 		    " ==> nxge_get_config_properties: N2"));
16686f45ec7bSml29623 		MUTEX_ENTER(&hw_p->nxge_cfg_lock);
16696f45ec7bSml29623 		if ((hw_p->flags & COMMON_CFG_VALID) !=
16706f45ec7bSml29623 		    COMMON_CFG_VALID) {
16716f45ec7bSml29623 			status = nxge_cfg_verify_set(nxgep,
16726f45ec7bSml29623 			    COMMON_RXDMA_GRP_CFG);
16736f45ec7bSml29623 			status = nxge_cfg_verify_set(nxgep,
16746f45ec7bSml29623 			    COMMON_CLASS_CFG);
16756f45ec7bSml29623 			hw_p->flags |= COMMON_CFG_VALID;
16766f45ec7bSml29623 		}
16776f45ec7bSml29623 		MUTEX_EXIT(&hw_p->nxge_cfg_lock);
16786f45ec7bSml29623 		status = nxge_use_cfg_n2niu_properties(nxgep);
16796f45ec7bSml29623 		break;
168059ac0c16Sdavemq 	default:
16812e59129aSraghus 		if (!NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
168259ac0c16Sdavemq 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
168359ac0c16Sdavemq 			    " nxge_get_config_properties:"
168459ac0c16Sdavemq 			    " unknown NIU type 0x%x", nxgep->niu_type));
168559ac0c16Sdavemq 			return (NXGE_ERROR);
168659ac0c16Sdavemq 		}
16876f45ec7bSml29623 
16886f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, VPD_CTL,
16896f45ec7bSml29623 		    " ==> nxge_get_config_properties: Neptune"));
16906f45ec7bSml29623 		status = nxge_cfg_verify_set_quick_config(nxgep);
16916f45ec7bSml29623 		MUTEX_ENTER(&hw_p->nxge_cfg_lock);
16926f45ec7bSml29623 		if ((hw_p->flags & COMMON_CFG_VALID) !=
16936f45ec7bSml29623 		    COMMON_CFG_VALID) {
16946f45ec7bSml29623 			status = nxge_cfg_verify_set(nxgep,
16956f45ec7bSml29623 			    COMMON_TXDMA_CFG);
16966f45ec7bSml29623 			status = nxge_cfg_verify_set(nxgep,
16976f45ec7bSml29623 			    COMMON_RXDMA_CFG);
16986f45ec7bSml29623 			status = nxge_cfg_verify_set(nxgep,
16996f45ec7bSml29623 			    COMMON_RXDMA_GRP_CFG);
17006f45ec7bSml29623 			status = nxge_cfg_verify_set(nxgep,
17016f45ec7bSml29623 			    COMMON_CLASS_CFG);
17026f45ec7bSml29623 			hw_p->flags |= COMMON_CFG_VALID;
17036f45ec7bSml29623 		}
17046f45ec7bSml29623 		MUTEX_EXIT(&hw_p->nxge_cfg_lock);
17056f45ec7bSml29623 		nxge_use_cfg_neptune_properties(nxgep);
17066f45ec7bSml29623 		status = NXGE_OK;
17076f45ec7bSml29623 		break;
17086f45ec7bSml29623 	}
17096f45ec7bSml29623 
17103d16f8e7Sml29623 	/*
17113d16f8e7Sml29623 	 * Get the software LSO enable flag property from the
17123d16f8e7Sml29623 	 * driver configuration file (nxge.conf).
17133d16f8e7Sml29623 	 * This flag will be set to disable (0) if this property
17143d16f8e7Sml29623 	 * does not exist.
17153d16f8e7Sml29623 	 */
17163d16f8e7Sml29623 	nxgep->soft_lso_enable = ddi_prop_get_int(DDI_DEV_T_ANY, nxgep->dip,
17173d16f8e7Sml29623 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "soft-lso-enable", 0);
17183d16f8e7Sml29623 	NXGE_DEBUG_MSG((nxgep, VPD_CTL,
17193d16f8e7Sml29623 	    "nxge_get_config_properties: software lso %d\n",
17203d16f8e7Sml29623 	    nxgep->soft_lso_enable));
17213d16f8e7Sml29623 
17224df55fdeSJanie Lu 	nxgep->niu_hw_type = NIU_HW_TYPE_DEFAULT;
17234df55fdeSJanie Lu 	if (nxgep->niu_type == N2_NIU) {
17249d587972SSantwona Behera 
17259d587972SSantwona Behera 		uchar_t *s_prop_val;
17269d587972SSantwona Behera 
17274df55fdeSJanie Lu 		/*
17284df55fdeSJanie Lu 		 * For NIU, the next generation KT has
17294df55fdeSJanie Lu 		 * a few differences in features that the
17304df55fdeSJanie Lu 		 * driver needs to handle them
17314df55fdeSJanie Lu 		 * accordingly.
17324df55fdeSJanie Lu 		 */
17334df55fdeSJanie Lu 		if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, nxgep->dip, 0,
17344df55fdeSJanie Lu 		    "compatible", &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
17354df55fdeSJanie Lu 			for (i = 0; i < prop_len; i++) {
17364df55fdeSJanie Lu 				if ((strcmp((caddr_t)prop_val[i],
17374df55fdeSJanie Lu 				    KT_NIU_COMPATIBLE) == 0)) {
17384df55fdeSJanie Lu 					nxgep->niu_hw_type = NIU_HW_TYPE_RF;
17394df55fdeSJanie Lu 					NXGE_DEBUG_MSG((nxgep, VPD_CTL,
17404df55fdeSJanie Lu 					    "NIU type %d", nxgep->niu_hw_type));
17414df55fdeSJanie Lu 					break;
17424df55fdeSJanie Lu 				}
17434df55fdeSJanie Lu 			}
17444df55fdeSJanie Lu 		}
17454df55fdeSJanie Lu 
17464df55fdeSJanie Lu 		ddi_prop_free(prop_val);
17479d587972SSantwona Behera 		/*
17489d587972SSantwona Behera 		 * Some Serdes and PHY properties may also be provided as OBP
17499d587972SSantwona Behera 		 * properties
17509d587972SSantwona Behera 		 */
17519d587972SSantwona Behera 		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
17529d587972SSantwona Behera 		    "tx-cfg-l", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) {
17539d587972SSantwona Behera 			nxgep->srds_prop.tx_cfg_l =
17549d587972SSantwona Behera 			    (uint16_t)(*(uint32_t *)s_prop_val);
17559d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, VPD_CTL,
17569d587972SSantwona Behera 			    "nxge_get_config_properties: "
17579d587972SSantwona Behera 			    "tx_cfg_l 0x%x, Read from OBP",
17589d587972SSantwona Behera 			    nxgep->srds_prop.tx_cfg_l));
17599d587972SSantwona Behera 			nxgep->srds_prop.prop_set |= NXGE_SRDS_TXCFGL;
17609d587972SSantwona Behera 			ddi_prop_free(s_prop_val);
17619d587972SSantwona Behera 		}
17629d587972SSantwona Behera 		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
17639d587972SSantwona Behera 		    "tx-cfg-h", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) {
17649d587972SSantwona Behera 			nxgep->srds_prop.tx_cfg_h =
17659d587972SSantwona Behera 			    (uint16_t)(*(uint32_t *)s_prop_val);
17669d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, VPD_CTL,
17679d587972SSantwona Behera 			    "nxge_get_config_properties: "
17689d587972SSantwona Behera 			    "tx_cfg_h 0x%x, Read from OBP",
17699d587972SSantwona Behera 			    nxgep->srds_prop.tx_cfg_h));
17709d587972SSantwona Behera 			nxgep->srds_prop.prop_set |= NXGE_SRDS_TXCFGH;
17719d587972SSantwona Behera 			ddi_prop_free(s_prop_val);
17729d587972SSantwona Behera 		}
17739d587972SSantwona Behera 		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
17749d587972SSantwona Behera 		    "rx-cfg-l", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) {
17759d587972SSantwona Behera 			nxgep->srds_prop.rx_cfg_l =
17769d587972SSantwona Behera 			    (uint16_t)(*(uint32_t *)s_prop_val);
17779d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, VPD_CTL,
17789d587972SSantwona Behera 			    "nxge_get_config_properties: "
17799d587972SSantwona Behera 			    "rx_cfg_l 0x%x, Read from OBP",
17809d587972SSantwona Behera 			    nxgep->srds_prop.rx_cfg_l));
17819d587972SSantwona Behera 			nxgep->srds_prop.prop_set |= NXGE_SRDS_RXCFGL;
17829d587972SSantwona Behera 			ddi_prop_free(s_prop_val);
17839d587972SSantwona Behera 		}
17849d587972SSantwona Behera 		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
17859d587972SSantwona Behera 		    "rx-cfg-h", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) {
17869d587972SSantwona Behera 			nxgep->srds_prop.rx_cfg_h =
17879d587972SSantwona Behera 			    (uint16_t)(*(uint32_t *)s_prop_val);
17889d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, VPD_CTL,
17899d587972SSantwona Behera 			    "nxge_get_config_properties: "
17909d587972SSantwona Behera 			    "rx_cfg_h 0x%x, Read from OBP",
17919d587972SSantwona Behera 			    nxgep->srds_prop.rx_cfg_h));
17929d587972SSantwona Behera 			nxgep->srds_prop.prop_set |= NXGE_SRDS_RXCFGH;
17939d587972SSantwona Behera 			ddi_prop_free(s_prop_val);
17949d587972SSantwona Behera 		}
17959d587972SSantwona Behera 		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
17969d587972SSantwona Behera 		    "pll-cfg", &s_prop_val, &prop_len) == DDI_PROP_SUCCESS) {
17979d587972SSantwona Behera 			nxgep->srds_prop.pll_cfg_l =
17989d587972SSantwona Behera 			    (uint16_t)(*(uint32_t *)s_prop_val);
17999d587972SSantwona Behera 			NXGE_DEBUG_MSG((nxgep, VPD_CTL,
18009d587972SSantwona Behera 			    "nxge_get_config_properties: "
18019d587972SSantwona Behera 			    "pll_cfg_l 0x%x, Read from OBP",
18029d587972SSantwona Behera 			    nxgep->srds_prop.pll_cfg_l));
18039d587972SSantwona Behera 			nxgep->srds_prop.prop_set |= NXGE_SRDS_PLLCFGL;
18049d587972SSantwona Behera 			ddi_prop_free(s_prop_val);
18059d587972SSantwona Behera 		}
18069d587972SSantwona Behera 		if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
18079d587972SSantwona Behera 		    "phy-reg-values", &s_prop_val, &prop_len) ==
18089d587972SSantwona Behera 		    DDI_PROP_SUCCESS) {
18099d587972SSantwona Behera 
18109d587972SSantwona Behera 			int tun_cnt, i;
18119d587972SSantwona Behera 			uchar_t *arr = s_prop_val;
18129d587972SSantwona Behera 
18139d587972SSantwona Behera 			tun_cnt = prop_len / 6; /* 3 values, 2 bytes each */
18149d587972SSantwona Behera 			nxgep->phy_prop.arr =
18159d587972SSantwona Behera 			    KMEM_ZALLOC(sizeof (nxge_phy_mdio_val_t) * tun_cnt,
18169d587972SSantwona Behera 			    KM_SLEEP);
18179d587972SSantwona Behera 			nxgep->phy_prop.cnt = tun_cnt;
18189d587972SSantwona Behera 			for (i = 0; i < tun_cnt; i++) {
18199d587972SSantwona Behera 				nxgep->phy_prop.arr[i].dev = *(uint16_t *)arr;
18209d587972SSantwona Behera 				arr += 2;
18219d587972SSantwona Behera 				nxgep->phy_prop.arr[i].reg = *(uint16_t *)arr;
18229d587972SSantwona Behera 				arr += 2;
18239d587972SSantwona Behera 				nxgep->phy_prop.arr[i].val = *(uint16_t *)arr;
18249d587972SSantwona Behera 				arr += 2;
18259d587972SSantwona Behera 				NXGE_DEBUG_MSG((nxgep, VPD_CTL,
18269d587972SSantwona Behera 				    "nxge_get_config_properties: From OBP, "
18279d587972SSantwona Behera 				    "read PHY <dev.reg.val> = "
18289d587972SSantwona Behera 				    "<0x%x.0x%x.0x%x>",
18299d587972SSantwona Behera 				    nxgep->phy_prop.arr[i].dev,
18309d587972SSantwona Behera 				    nxgep->phy_prop.arr[i].reg,
18319d587972SSantwona Behera 				    nxgep->phy_prop.arr[i].val));
18329d587972SSantwona Behera 			}
18339d587972SSantwona Behera 			ddi_prop_free(s_prop_val);
18349d587972SSantwona Behera 		}
18354df55fdeSJanie Lu 	}
18364df55fdeSJanie Lu 
18376f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, VPD_CTL, " <== nxge_get_config_properties"));
18386f45ec7bSml29623 	return (status);
18396f45ec7bSml29623 }
18406f45ec7bSml29623 
18416f45ec7bSml29623 static nxge_status_t
18426f45ec7bSml29623 nxge_use_cfg_n2niu_properties(p_nxge_t nxgep)
18436f45ec7bSml29623 {
18446f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
18456f45ec7bSml29623 
18466f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_n2niu_properties"));
18476f45ec7bSml29623 
18486f45ec7bSml29623 	status = nxge_use_default_dma_config_n2(nxgep);
18496f45ec7bSml29623 	if (status != NXGE_OK) {
18506f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
18516f45ec7bSml29623 		    " ==> nxge_use_cfg_n2niu_properties (err 0x%x)",
18526f45ec7bSml29623 		    status));
18536f45ec7bSml29623 		return (status | NXGE_ERROR);
18546f45ec7bSml29623 	}
18556f45ec7bSml29623 
18566f45ec7bSml29623 	(void) nxge_use_cfg_vlan_class_config(nxgep);
18576f45ec7bSml29623 	(void) nxge_use_cfg_mac_class_config(nxgep);
18586f45ec7bSml29623 	(void) nxge_use_cfg_class_config(nxgep);
18596f45ec7bSml29623 	(void) nxge_use_cfg_link_cfg(nxgep);
18606f45ec7bSml29623 
18616f45ec7bSml29623 	/*
18626f45ec7bSml29623 	 * Read in the hardware (fcode) properties. Use the ndd array to read
18636f45ec7bSml29623 	 * each property.
18646f45ec7bSml29623 	 */
18656f45ec7bSml29623 	(void) nxge_get_param_soft_properties(nxgep);
18666f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_n2niu_properties"));
18676f45ec7bSml29623 
18686f45ec7bSml29623 	return (status);
18696f45ec7bSml29623 }
18706f45ec7bSml29623 
18716f45ec7bSml29623 static void
18726f45ec7bSml29623 nxge_use_cfg_neptune_properties(p_nxge_t nxgep)
18736f45ec7bSml29623 {
18746f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_neptune_properties"));
18756f45ec7bSml29623 
18766f45ec7bSml29623 	(void) nxge_use_cfg_dma_config(nxgep);
18776f45ec7bSml29623 	(void) nxge_use_cfg_vlan_class_config(nxgep);
18786f45ec7bSml29623 	(void) nxge_use_cfg_mac_class_config(nxgep);
18796f45ec7bSml29623 	(void) nxge_use_cfg_class_config(nxgep);
18806f45ec7bSml29623 	(void) nxge_use_cfg_link_cfg(nxgep);
18816f45ec7bSml29623 
18826f45ec7bSml29623 	/*
18836f45ec7bSml29623 	 * Read in the hardware (fcode) properties. Use the ndd array to read
18846f45ec7bSml29623 	 * each property.
18856f45ec7bSml29623 	 */
18866f45ec7bSml29623 	(void) nxge_get_param_soft_properties(nxgep);
18876f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_neptune_properties"));
18886f45ec7bSml29623 }
18896f45ec7bSml29623 
18906f45ec7bSml29623 /*
1891952a2464SMichael Speer  * FWARC 2006/556 for N2 NIU.  Get the properties
1892952a2464SMichael Speer  * from the prom.
18936f45ec7bSml29623  */
18946f45ec7bSml29623 static nxge_status_t
18956f45ec7bSml29623 nxge_use_default_dma_config_n2(p_nxge_t nxgep)
18966f45ec7bSml29623 {
18976f45ec7bSml29623 	int			ndmas;
18986f45ec7bSml29623 	uint8_t			func;
18996f45ec7bSml29623 	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
19006f45ec7bSml29623 	p_nxge_hw_pt_cfg_t	p_cfgp;
19016f45ec7bSml29623 	int			*prop_val;
19026f45ec7bSml29623 	uint_t			prop_len;
19036f45ec7bSml29623 	int			i;
19046f45ec7bSml29623 	nxge_status_t		status = NXGE_OK;
19056f45ec7bSml29623 
19066f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2"));
19076f45ec7bSml29623 
19086f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
19096f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
19106f45ec7bSml29623 
19116f45ec7bSml29623 	func = nxgep->function_num;
19126f45ec7bSml29623 	p_cfgp->function_number = func;
19136f45ec7bSml29623 	ndmas = NXGE_TDMA_PER_NIU_PORT;
19146f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
19156f45ec7bSml29623 	    "tx-dma-channels", (int **)&prop_val,
19166f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
1917952a2464SMichael Speer 		if (prop_len != NXGE_NIU_TDMA_PROP_LEN) {
1918952a2464SMichael Speer 			ddi_prop_free(prop_val);
1919952a2464SMichael Speer 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1920952a2464SMichael Speer 			    "==> nxge_use_default_dma_config_n2: "
1921290b5530SMichael Speer 			    "invalid tx-dma-channels property for the NIU, "
1922290b5530SMichael Speer 			    "using defaults"));
1923290b5530SMichael Speer 			/*
1924290b5530SMichael Speer 			 * Just failover to defaults
1925290b5530SMichael Speer 			 */
1926290b5530SMichael Speer 			p_cfgp->tdc.start = (func * NXGE_TDMA_PER_NIU_PORT);
1927290b5530SMichael Speer 			ndmas = NXGE_TDMA_PER_NIU_PORT;
1928952a2464SMichael Speer 		} else {
1929678453a8Sspeer 			p_cfgp->tdc.start = prop_val[0];
19306f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, OBP_CTL,
19316f45ec7bSml29623 			    "==> nxge_use_default_dma_config_n2: tdc starts %d "
1932678453a8Sspeer 			    "(#%d)", p_cfgp->tdc.start, prop_len));
19336f45ec7bSml29623 
19346f45ec7bSml29623 			ndmas = prop_val[1];
19356f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, OBP_CTL,
19366f45ec7bSml29623 			    "==> nxge_use_default_dma_config_n2: #tdc %d (#%d)",
19376f45ec7bSml29623 			    ndmas, prop_len));
19386f45ec7bSml29623 			ddi_prop_free(prop_val);
1939952a2464SMichael Speer 		}
19406f45ec7bSml29623 	} else {
19416f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19426f45ec7bSml29623 		    "==> nxge_use_default_dma_config_n2: "
19436f45ec7bSml29623 		    "get tx-dma-channels failed"));
19446f45ec7bSml29623 		return (NXGE_DDI_FAILED);
19456f45ec7bSml29623 	}
19466f45ec7bSml29623 
1947da14cebeSEric Cheng 	p_cfgp->tdc.count = ndmas;
1948678453a8Sspeer 	p_cfgp->tdc.owned = p_cfgp->tdc.count;
19496f45ec7bSml29623 
19506f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: "
1951da14cebeSEric Cheng 	    "p_cfgp 0x%llx max_tdcs %d start %d",
1952da14cebeSEric Cheng 	    p_cfgp, p_cfgp->tdc.count, p_cfgp->tdc.start));
19536f45ec7bSml29623 
19546f45ec7bSml29623 	/* Receive DMA */
19556f45ec7bSml29623 	ndmas = NXGE_RDMA_PER_NIU_PORT;
19566f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
19576f45ec7bSml29623 	    "rx-dma-channels", (int **)&prop_val,
19586f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
1959290b5530SMichael Speer 		if (prop_len != NXGE_NIU_RDMA_PROP_LEN) {
1960952a2464SMichael Speer 			ddi_prop_free(prop_val);
1961952a2464SMichael Speer 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
1962952a2464SMichael Speer 			    "==> nxge_use_default_dma_config_n2: "
1963290b5530SMichael Speer 			    "invalid rx-dma-channels property for the NIU, "
1964290b5530SMichael Speer 			    "using defaults"));
1965290b5530SMichael Speer 			/*
1966290b5530SMichael Speer 			 * Just failover to defaults
1967290b5530SMichael Speer 			 */
1968290b5530SMichael Speer 			p_cfgp->start_rdc = (func * NXGE_RDMA_PER_NIU_PORT);
1969290b5530SMichael Speer 			ndmas = NXGE_RDMA_PER_NIU_PORT;
1970952a2464SMichael Speer 		} else {
19716f45ec7bSml29623 			p_cfgp->start_rdc = prop_val[0];
19726f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, OBP_CTL,
1973952a2464SMichael Speer 			    "==> nxge_use_default_dma_config_n2(obp):"
1974952a2464SMichael Speer 			    " rdc start %d (#%d)",
1975952a2464SMichael Speer 			    p_cfgp->start_rdc, prop_len));
19766f45ec7bSml29623 			ndmas = prop_val[1];
19776f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, OBP_CTL,
1978952a2464SMichael Speer 			    "==> nxge_use_default_dma_config_n2(obp): "
1979952a2464SMichael Speer 			    "#rdc %d (#%d)", ndmas, prop_len));
19806f45ec7bSml29623 			ddi_prop_free(prop_val);
1981952a2464SMichael Speer 		}
19826f45ec7bSml29623 	} else {
19836f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
19846f45ec7bSml29623 		    "==> nxge_use_default_dma_config_n2: "
19856f45ec7bSml29623 		    "get rx-dma-channel failed"));
19866f45ec7bSml29623 		return (NXGE_DDI_FAILED);
19876f45ec7bSml29623 	}
19886f45ec7bSml29623 
1989da14cebeSEric Cheng 	p_cfgp->max_rdcs = ndmas;
19906f45ec7bSml29623 	nxgep->rdc_mask = (ndmas - 1);
19916f45ec7bSml29623 
19926f45ec7bSml29623 	/* Hypervisor: rdc # and group # use the same # !! */
1993678453a8Sspeer 	p_cfgp->max_grpids = p_cfgp->max_rdcs + p_cfgp->tdc.owned;
19946f45ec7bSml29623 	p_cfgp->mif_ldvid = p_cfgp->mac_ldvid = p_cfgp->ser_ldvid = 0;
19956f45ec7bSml29623 
19966f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
19976f45ec7bSml29623 	    "interrupts", (int **)&prop_val,
19986f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
1999952a2464SMichael Speer 		if ((prop_len != NXGE_NIU_0_INTR_PROP_LEN) &&
2000952a2464SMichael Speer 		    (prop_len != NXGE_NIU_1_INTR_PROP_LEN)) {
2001952a2464SMichael Speer 			ddi_prop_free(prop_val);
2002952a2464SMichael Speer 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
2003952a2464SMichael Speer 			    "==> nxge_use_default_dma_config_n2: "
2004952a2464SMichael Speer 			    "get interrupts failed"));
2005952a2464SMichael Speer 			return (NXGE_DDI_FAILED);
2006952a2464SMichael Speer 		}
2007952a2464SMichael Speer 
20086f45ec7bSml29623 		/*
20096f45ec7bSml29623 		 * For each device assigned, the content of each interrupts
20106f45ec7bSml29623 		 * property is its logical device group.
20116f45ec7bSml29623 		 *
20126f45ec7bSml29623 		 * Assignment of interrupts property is in the the following
20136f45ec7bSml29623 		 * order:
20146f45ec7bSml29623 		 *
20156f45ec7bSml29623 		 * MAC MIF (if configured) SYSTEM ERROR (if configured) first
20166f45ec7bSml29623 		 * receive channel next channel...... last receive channel
20176f45ec7bSml29623 		 * first transmit channel next channel...... last transmit
20186f45ec7bSml29623 		 * channel
20196f45ec7bSml29623 		 *
20206f45ec7bSml29623 		 * prop_len should be at least for one mac and total # of rx and
20216f45ec7bSml29623 		 * tx channels. Function 0 owns MIF and ERROR
20226f45ec7bSml29623 		 */
20236f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, OBP_CTL,
20246f45ec7bSml29623 		    "==> nxge_use_default_dma_config_n2(obp): "
20256f45ec7bSml29623 		    "# interrupts %d", prop_len));
20266f45ec7bSml29623 
20276f45ec7bSml29623 		switch (func) {
20286f45ec7bSml29623 		case 0:
20296f45ec7bSml29623 			p_cfgp->ldg_chn_start = 3;
20306f45ec7bSml29623 			p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT0;
20316f45ec7bSml29623 			p_cfgp->mif_ldvid = NXGE_MIF_LD;
20326f45ec7bSml29623 			p_cfgp->ser_ldvid = NXGE_SYS_ERROR_LD;
20336f45ec7bSml29623 
20346f45ec7bSml29623 			break;
20356f45ec7bSml29623 		case 1:
20366f45ec7bSml29623 			p_cfgp->ldg_chn_start = 1;
20376f45ec7bSml29623 			p_cfgp->mac_ldvid = NXGE_MAC_LD_PORT1;
20386f45ec7bSml29623 
20396f45ec7bSml29623 			break;
20406f45ec7bSml29623 		default:
20416f45ec7bSml29623 			status = NXGE_DDI_FAILED;
20426f45ec7bSml29623 			break;
20436f45ec7bSml29623 		}
20446f45ec7bSml29623 
20456f45ec7bSml29623 		if (status != NXGE_OK)
20466f45ec7bSml29623 			return (status);
20476f45ec7bSml29623 
20486f45ec7bSml29623 		for (i = 0; i < prop_len; i++) {
20496f45ec7bSml29623 			p_cfgp->ldg[i] = prop_val[i];
20506f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, OBP_CTL,
20516f45ec7bSml29623 			    "==> nxge_use_default_dma_config_n2(obp): "
2052678453a8Sspeer 			    "F%d: interrupt #%d, ldg %d",
2053678453a8Sspeer 			    nxgep->function_num, i, p_cfgp->ldg[i]));
20546f45ec7bSml29623 		}
20556f45ec7bSml29623 
20566f45ec7bSml29623 		p_cfgp->max_grpids = prop_len;
20576f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, OBP_CTL,
20586f45ec7bSml29623 		    "==> nxge_use_default_dma_config_n2(obp): %d "
20596f45ec7bSml29623 		    "(#%d) maxgrpids %d channel starts %d",
20606f45ec7bSml29623 		    p_cfgp->mac_ldvid, i, p_cfgp->max_grpids,
20616f45ec7bSml29623 		    p_cfgp->ldg_chn_start));
20626f45ec7bSml29623 		ddi_prop_free(prop_val);
20636f45ec7bSml29623 	} else {
20646f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
20656f45ec7bSml29623 		    "==> nxge_use_default_dma_config_n2: "
20666f45ec7bSml29623 		    "get interrupts failed"));
20676f45ec7bSml29623 		return (NXGE_DDI_FAILED);
20686f45ec7bSml29623 	}
20696f45ec7bSml29623 
20706f45ec7bSml29623 	p_cfgp->max_ldgs = p_cfgp->max_grpids;
20716f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL,
2072da14cebeSEric Cheng 	    "==> nxge_use_default_dma_config_n2: p_cfgp 0x%llx max_rdcs %d "
2073da14cebeSEric Cheng 	    "max_grpids %d macid %d mifid %d serrid %d",
2074da14cebeSEric Cheng 	    p_cfgp, p_cfgp->max_rdcs, p_cfgp->max_grpids,
20756f45ec7bSml29623 	    p_cfgp->mac_ldvid, p_cfgp->mif_ldvid, p_cfgp->ser_ldvid));
20766f45ec7bSml29623 
2077da14cebeSEric Cheng 
20786f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: "
20796f45ec7bSml29623 	    "p_cfgp p%p start_ldg %d nxgep->max_ldgs %d",
20806f45ec7bSml29623 	    p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs));
20816f45ec7bSml29623 
20826f45ec7bSml29623 	/*
20836f45ec7bSml29623 	 * RDC groups and the beginning RDC group assigned to this function.
20846f45ec7bSml29623 	 */
2085da14cebeSEric Cheng 	p_cfgp->max_rdc_grpids = NXGE_MAX_RDC_GROUPS / nxgep->nports;
2086da14cebeSEric Cheng 	p_cfgp->def_mac_rxdma_grpid =
2087da14cebeSEric Cheng 	    nxgep->function_num * NXGE_MAX_RDC_GROUPS / nxgep->nports;
2088da14cebeSEric Cheng 	p_cfgp->def_mac_txdma_grpid =
2089da14cebeSEric Cheng 	    nxgep->function_num * NXGE_MAX_TDC_GROUPS / nxgep->nports;
2090678453a8Sspeer 
2091da14cebeSEric Cheng 	if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind(nxgep,
2092da14cebeSEric Cheng 	    p_cfgp->def_mac_rxdma_grpid, B_TRUE)) >= NXGE_MAX_RDC_GRPS) {
2093678453a8Sspeer 		NXGE_ERROR_MSG((nxgep, CFG_CTL,
2094678453a8Sspeer 		    "nxge_use_default_dma_config_n2(): "
2095678453a8Sspeer 		    "nxge_fzc_rdc_tbl_bind failed"));
2096678453a8Sspeer 		return (NXGE_DDI_FAILED);
2097678453a8Sspeer 	}
20986f45ec7bSml29623 
20996f45ec7bSml29623 	status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
2100678453a8Sspeer 	    "rx-rdc-grps", p_cfgp->max_rdc_grpids);
21016f45ec7bSml29623 	if (status) {
21026f45ec7bSml29623 		return (NXGE_DDI_FAILED);
21036f45ec7bSml29623 	}
21046f45ec7bSml29623 	status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
2105678453a8Sspeer 	    "rx-rdc-grps-begin", p_cfgp->def_mac_rxdma_grpid);
21066f45ec7bSml29623 	if (status) {
21076f45ec7bSml29623 		(void) ddi_prop_remove(DDI_DEV_T_NONE, nxgep->dip,
21086f45ec7bSml29623 		    "rx-rdc-grps");
21096f45ec7bSml29623 		return (NXGE_DDI_FAILED);
21106f45ec7bSml29623 	}
21116f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL, "==> nxge_use_default_dma_config_n2: "
21126f45ec7bSml29623 	    "p_cfgp $%p # rdc groups %d start rdc group id %d",
21136f45ec7bSml29623 	    p_cfgp, p_cfgp->max_rdc_grpids,
2114678453a8Sspeer 	    p_cfgp->def_mac_rxdma_grpid));
21156f45ec7bSml29623 
2116c1f9c6e5SSantwona Behera 	nxgep->intr_timeout = NXGE_RDC_RCR_TIMEOUT;
2117c1f9c6e5SSantwona Behera 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
2118c1f9c6e5SSantwona Behera 	    "rxdma-intr-time", (int **)&prop_val, &prop_len) ==
2119c1f9c6e5SSantwona Behera 	    DDI_PROP_SUCCESS) {
2120c1f9c6e5SSantwona Behera 		if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2121c1f9c6e5SSantwona Behera 			nxgep->intr_timeout = prop_val[0];
2122c1f9c6e5SSantwona Behera 			(void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
2123c1f9c6e5SSantwona Behera 			    nxgep->dip, "rxdma-intr-time", prop_val, prop_len);
2124c1f9c6e5SSantwona Behera 		}
2125c1f9c6e5SSantwona Behera 		ddi_prop_free(prop_val);
2126c1f9c6e5SSantwona Behera 	}
2127c1f9c6e5SSantwona Behera 
2128c1f9c6e5SSantwona Behera 	nxgep->intr_threshold = NXGE_RDC_RCR_THRESHOLD;
2129c1f9c6e5SSantwona Behera 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
2130c1f9c6e5SSantwona Behera 	    "rxdma-intr-pkts", (int **)&prop_val, &prop_len) ==
2131c1f9c6e5SSantwona Behera 	    DDI_PROP_SUCCESS) {
2132c1f9c6e5SSantwona Behera 		if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2133c1f9c6e5SSantwona Behera 			nxgep->intr_threshold = prop_val[0];
2134c1f9c6e5SSantwona Behera 			(void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
2135c1f9c6e5SSantwona Behera 			    nxgep->dip, "rxdma-intr-pkts", prop_val, prop_len);
2136c1f9c6e5SSantwona Behera 		}
2137c1f9c6e5SSantwona Behera 		ddi_prop_free(prop_val);
2138c1f9c6e5SSantwona Behera 	}
2139c1f9c6e5SSantwona Behera 
21406f45ec7bSml29623 	nxge_set_hw_dma_config(nxgep);
21416f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL, "<== nxge_use_default_dma_config_n2"));
21426f45ec7bSml29623 	return (status);
21436f45ec7bSml29623 }
21446f45ec7bSml29623 
21456f45ec7bSml29623 static void
21466f45ec7bSml29623 nxge_use_cfg_dma_config(p_nxge_t nxgep)
21476f45ec7bSml29623 {
214859ac0c16Sdavemq 	int tx_ndmas, rx_ndmas, nrxgp, st_txdma, st_rxdma;
21496f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
21506f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
21516f45ec7bSml29623 	dev_info_t *dip;
21526f45ec7bSml29623 	p_nxge_param_t param_arr;
21536f45ec7bSml29623 	char *prop;
21546f45ec7bSml29623 	int *prop_val;
21556f45ec7bSml29623 	uint_t prop_len;
215659ac0c16Sdavemq 	int i;
215759ac0c16Sdavemq 	uint8_t *ch_arr_p;
21586f45ec7bSml29623 
21596f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_dma_config"));
21606f45ec7bSml29623 	param_arr = nxgep->param_arr;
21616f45ec7bSml29623 
21626f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
21636f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
21646f45ec7bSml29623 	dip = nxgep->dip;
21656f45ec7bSml29623 	p_cfgp->function_number = nxgep->function_num;
21666f45ec7bSml29623 	prop = param_arr[param_txdma_channels_begin].fcode_name;
21676f45ec7bSml29623 
21686f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
21696f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
2170678453a8Sspeer 		p_cfgp->tdc.start = *prop_val;
21716f45ec7bSml29623 		ddi_prop_free(prop_val);
21726f45ec7bSml29623 	} else {
217359ac0c16Sdavemq 		switch (nxgep->niu_type) {
217459ac0c16Sdavemq 		case NEPTUNE_4_1GC:
217559ac0c16Sdavemq 			ch_arr_p = &tx_4_1G[0];
217659ac0c16Sdavemq 			break;
217759ac0c16Sdavemq 		case NEPTUNE_2_10GF:
217859ac0c16Sdavemq 			ch_arr_p = &tx_2_10G[0];
217959ac0c16Sdavemq 			break;
218059ac0c16Sdavemq 		case NEPTUNE_2_10GF_2_1GC:
218159a835ddSjoycey 		case NEPTUNE_2_10GF_2_1GRF:
218259ac0c16Sdavemq 			ch_arr_p = &tx_2_10G_2_1G[0];
218359ac0c16Sdavemq 			break;
218459ac0c16Sdavemq 		case NEPTUNE_1_10GF_3_1GC:
218559ac0c16Sdavemq 			ch_arr_p = &tx_1_10G_3_1G[0];
218659ac0c16Sdavemq 			break;
218759ac0c16Sdavemq 		case NEPTUNE_1_1GC_1_10GF_2_1GC:
218859ac0c16Sdavemq 			ch_arr_p = &tx_1_1G_1_10G_2_1G[0];
218959ac0c16Sdavemq 			break;
219059ac0c16Sdavemq 		default:
2191d81011f0Ssbehera 			switch (nxgep->platform_type) {
2192d81011f0Ssbehera 			case P_NEPTUNE_ALONSO:
2193d81011f0Ssbehera 				ch_arr_p = &tx_2_10G_2_1G[0];
2194d81011f0Ssbehera 				break;
2195d81011f0Ssbehera 			default:
219659ac0c16Sdavemq 				ch_arr_p = &p4_tx_equal[0];
219759ac0c16Sdavemq 				break;
21986f45ec7bSml29623 			}
2199d81011f0Ssbehera 			break;
2200d81011f0Ssbehera 		}
220159ac0c16Sdavemq 		st_txdma = 0;
220259ac0c16Sdavemq 		for (i = 0; i < nxgep->function_num; i++, ch_arr_p++)
220359ac0c16Sdavemq 			st_txdma += *ch_arr_p;
220459ac0c16Sdavemq 
22056f45ec7bSml29623 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
220659ac0c16Sdavemq 		    prop, st_txdma);
2207678453a8Sspeer 		p_cfgp->tdc.start = st_txdma;
22086f45ec7bSml29623 	}
22096f45ec7bSml29623 
22106f45ec7bSml29623 	prop = param_arr[param_txdma_channels].fcode_name;
22116f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
22126f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
22136f45ec7bSml29623 		tx_ndmas = *prop_val;
22146f45ec7bSml29623 		ddi_prop_free(prop_val);
22156f45ec7bSml29623 	} else {
221659ac0c16Sdavemq 		switch (nxgep->niu_type) {
221759ac0c16Sdavemq 		case NEPTUNE_4_1GC:
221859ac0c16Sdavemq 			tx_ndmas = tx_4_1G[nxgep->function_num];
221959ac0c16Sdavemq 			break;
222059ac0c16Sdavemq 		case NEPTUNE_2_10GF:
222159ac0c16Sdavemq 			tx_ndmas = tx_2_10G[nxgep->function_num];
222259ac0c16Sdavemq 			break;
222359ac0c16Sdavemq 		case NEPTUNE_2_10GF_2_1GC:
222459a835ddSjoycey 		case NEPTUNE_2_10GF_2_1GRF:
222559ac0c16Sdavemq 			tx_ndmas = tx_2_10G_2_1G[nxgep->function_num];
222659ac0c16Sdavemq 			break;
222759ac0c16Sdavemq 		case NEPTUNE_1_10GF_3_1GC:
222859ac0c16Sdavemq 			tx_ndmas = tx_1_10G_3_1G[nxgep->function_num];
222959ac0c16Sdavemq 			break;
223059ac0c16Sdavemq 		case NEPTUNE_1_1GC_1_10GF_2_1GC:
223159ac0c16Sdavemq 			tx_ndmas = tx_1_1G_1_10G_2_1G[nxgep->function_num];
223259ac0c16Sdavemq 			break;
223359ac0c16Sdavemq 		default:
2234d81011f0Ssbehera 			switch (nxgep->platform_type) {
2235d81011f0Ssbehera 			case P_NEPTUNE_ALONSO:
2236d81011f0Ssbehera 				tx_ndmas = tx_2_10G_2_1G[nxgep->function_num];
2237d81011f0Ssbehera 				break;
2238d81011f0Ssbehera 			default:
223959ac0c16Sdavemq 				tx_ndmas = p4_tx_equal[nxgep->function_num];
224059ac0c16Sdavemq 				break;
22416f45ec7bSml29623 			}
2242d81011f0Ssbehera 			break;
2243d81011f0Ssbehera 		}
22446f45ec7bSml29623 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
22456f45ec7bSml29623 		    prop, tx_ndmas);
22466f45ec7bSml29623 	}
22476f45ec7bSml29623 
2248da14cebeSEric Cheng 	p_cfgp->tdc.count = tx_ndmas;
2249678453a8Sspeer 	p_cfgp->tdc.owned = p_cfgp->tdc.count;
22506f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: "
2251da14cebeSEric Cheng 	    "p_cfgp 0x%llx max_tdcs %d", p_cfgp, p_cfgp->tdc.count));
22526f45ec7bSml29623 
22536f45ec7bSml29623 	prop = param_arr[param_rxdma_channels_begin].fcode_name;
22546f45ec7bSml29623 
22556f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
22566f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
22576f45ec7bSml29623 		p_cfgp->start_rdc = *prop_val;
22586f45ec7bSml29623 		ddi_prop_free(prop_val);
22596f45ec7bSml29623 	} else {
226059ac0c16Sdavemq 		switch (nxgep->niu_type) {
226159ac0c16Sdavemq 		case NEPTUNE_4_1GC:
226259ac0c16Sdavemq 			ch_arr_p = &rx_4_1G[0];
226359ac0c16Sdavemq 			break;
226459ac0c16Sdavemq 		case NEPTUNE_2_10GF:
226559ac0c16Sdavemq 			ch_arr_p = &rx_2_10G[0];
226659ac0c16Sdavemq 			break;
226759ac0c16Sdavemq 		case NEPTUNE_2_10GF_2_1GC:
226859a835ddSjoycey 		case NEPTUNE_2_10GF_2_1GRF:
226959ac0c16Sdavemq 			ch_arr_p = &rx_2_10G_2_1G[0];
227059ac0c16Sdavemq 			break;
227159ac0c16Sdavemq 		case NEPTUNE_1_10GF_3_1GC:
227259ac0c16Sdavemq 			ch_arr_p = &rx_1_10G_3_1G[0];
227359ac0c16Sdavemq 			break;
227459ac0c16Sdavemq 		case NEPTUNE_1_1GC_1_10GF_2_1GC:
227559ac0c16Sdavemq 			ch_arr_p = &rx_1_1G_1_10G_2_1G[0];
227659ac0c16Sdavemq 			break;
227759ac0c16Sdavemq 		default:
2278d81011f0Ssbehera 			switch (nxgep->platform_type) {
2279d81011f0Ssbehera 			case P_NEPTUNE_ALONSO:
2280d81011f0Ssbehera 				ch_arr_p = &rx_2_10G_2_1G[0];
2281d81011f0Ssbehera 				break;
2282d81011f0Ssbehera 			default:
228359ac0c16Sdavemq 				ch_arr_p = &p4_rx_equal[0];
228459ac0c16Sdavemq 				break;
22856f45ec7bSml29623 			}
2286d81011f0Ssbehera 			break;
2287d81011f0Ssbehera 		}
228859ac0c16Sdavemq 		st_rxdma = 0;
228959ac0c16Sdavemq 		for (i = 0; i < nxgep->function_num; i++, ch_arr_p++)
229059ac0c16Sdavemq 			st_rxdma += *ch_arr_p;
229159ac0c16Sdavemq 
22926f45ec7bSml29623 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
229359ac0c16Sdavemq 		    prop, st_rxdma);
229459ac0c16Sdavemq 		p_cfgp->start_rdc = st_rxdma;
22956f45ec7bSml29623 	}
22966f45ec7bSml29623 
22976f45ec7bSml29623 	prop = param_arr[param_rxdma_channels].fcode_name;
22986f45ec7bSml29623 
22996f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
23006f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
23016f45ec7bSml29623 		rx_ndmas = *prop_val;
23026f45ec7bSml29623 		ddi_prop_free(prop_val);
23036f45ec7bSml29623 	} else {
230459ac0c16Sdavemq 		switch (nxgep->niu_type) {
230559ac0c16Sdavemq 		case NEPTUNE_4_1GC:
230659ac0c16Sdavemq 			rx_ndmas = rx_4_1G[nxgep->function_num];
230759ac0c16Sdavemq 			break;
230859ac0c16Sdavemq 		case NEPTUNE_2_10GF:
230959ac0c16Sdavemq 			rx_ndmas = rx_2_10G[nxgep->function_num];
231059ac0c16Sdavemq 			break;
231159ac0c16Sdavemq 		case NEPTUNE_2_10GF_2_1GC:
231259a835ddSjoycey 		case NEPTUNE_2_10GF_2_1GRF:
231359ac0c16Sdavemq 			rx_ndmas = rx_2_10G_2_1G[nxgep->function_num];
231459ac0c16Sdavemq 			break;
231559ac0c16Sdavemq 		case NEPTUNE_1_10GF_3_1GC:
231659ac0c16Sdavemq 			rx_ndmas = rx_1_10G_3_1G[nxgep->function_num];
231759ac0c16Sdavemq 			break;
231859ac0c16Sdavemq 		case NEPTUNE_1_1GC_1_10GF_2_1GC:
231959ac0c16Sdavemq 			rx_ndmas = rx_1_1G_1_10G_2_1G[nxgep->function_num];
232059ac0c16Sdavemq 			break;
232159ac0c16Sdavemq 		default:
2322d81011f0Ssbehera 			switch (nxgep->platform_type) {
2323d81011f0Ssbehera 			case P_NEPTUNE_ALONSO:
2324d81011f0Ssbehera 				rx_ndmas = rx_2_10G_2_1G[nxgep->function_num];
2325d81011f0Ssbehera 				break;
2326d81011f0Ssbehera 			default:
232759ac0c16Sdavemq 				rx_ndmas = p4_rx_equal[nxgep->function_num];
232859ac0c16Sdavemq 				break;
23296f45ec7bSml29623 			}
2330d81011f0Ssbehera 			break;
2331d81011f0Ssbehera 		}
23326f45ec7bSml29623 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
23336f45ec7bSml29623 		    prop, rx_ndmas);
23346f45ec7bSml29623 	}
23356f45ec7bSml29623 
2336da14cebeSEric Cheng 	p_cfgp->max_rdcs = rx_ndmas;
23376f45ec7bSml29623 
2338da14cebeSEric Cheng 	/*
2339da14cebeSEric Cheng 	 * RDC groups and the beginning RDC group assigned to this function.
2340da14cebeSEric Cheng 	 * XXX: this may be wrong if prop value is used.
2341da14cebeSEric Cheng 	 */
2342da14cebeSEric Cheng 	p_cfgp->def_mac_rxdma_grpid =
2343da14cebeSEric Cheng 	    nxgep->function_num * NXGE_MAX_RDC_GROUPS / nxgep->nports;
2344da14cebeSEric Cheng 	p_cfgp->def_mac_txdma_grpid =
2345da14cebeSEric Cheng 	    nxgep->function_num * NXGE_MAX_TDC_GROUPS / nxgep->nports;
2346da14cebeSEric Cheng 
2347da14cebeSEric Cheng 	if ((p_cfgp->def_mac_rxdma_grpid = nxge_fzc_rdc_tbl_bind(nxgep,
2348da14cebeSEric Cheng 	    p_cfgp->def_mac_rxdma_grpid, B_TRUE)) >= NXGE_MAX_RDC_GRPS) {
2349678453a8Sspeer 		NXGE_ERROR_MSG((nxgep, CFG_CTL,
2350da14cebeSEric Cheng 		    "nxge_use_default_dma_config2(): "
2351678453a8Sspeer 		    "nxge_fzc_rdc_tbl_bind failed"));
2352678453a8Sspeer 		goto nxge_use_cfg_dma_config_exit;
2353678453a8Sspeer 	}
2354678453a8Sspeer 
23556f45ec7bSml29623 	prop = param_arr[param_rx_rdc_grps].fcode_name;
23566f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
23576f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
23586f45ec7bSml29623 		nrxgp = *prop_val;
23596f45ec7bSml29623 		ddi_prop_free(prop_val);
23606f45ec7bSml29623 	} else {
2361da14cebeSEric Cheng 		nrxgp = NXGE_MAX_RDC_GRPS / nxgep->nports;
23626f45ec7bSml29623 		(void) ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
23636f45ec7bSml29623 		    prop, nrxgp);
23646f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
23656f45ec7bSml29623 		    "==> nxge_use_default_dma_config: "
23666f45ec7bSml29623 		    "num_rdc_grpid not found: use def:# of "
23676f45ec7bSml29623 		    "rdc groups %d\n", nrxgp));
23686f45ec7bSml29623 	}
23696f45ec7bSml29623 	p_cfgp->max_rdc_grpids = nrxgp;
23706f45ec7bSml29623 
23716f45ec7bSml29623 	/*
23726f45ec7bSml29623 	 * 2/4 ports have the same hard-wired logical groups assigned.
23736f45ec7bSml29623 	 */
23746f45ec7bSml29623 	p_cfgp->start_ldg = nxgep->function_num * NXGE_LDGRP_PER_4PORTS;
23756f45ec7bSml29623 	p_cfgp->max_ldgs = NXGE_LDGRP_PER_4PORTS;
23766f45ec7bSml29623 
23776f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_default_dma_config: "
2378da14cebeSEric Cheng 	    "p_cfgp 0x%llx max_rdcs %d max_grpids %d default_grpid %d",
2379da14cebeSEric Cheng 	    p_cfgp, p_cfgp->max_rdcs, p_cfgp->max_grpids,
2380da14cebeSEric Cheng 	    p_cfgp->def_mac_rxdma_grpid));
23816f45ec7bSml29623 
23826f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_dma_config: "
23836f45ec7bSml29623 	    "p_cfgp 0x%016llx start_ldg %d nxgep->max_ldgs %d "
2384678453a8Sspeer 	    "def_mac_rxdma_grpid %d",
23856f45ec7bSml29623 	    p_cfgp, p_cfgp->start_ldg, p_cfgp->max_ldgs,
2386678453a8Sspeer 	    p_cfgp->def_mac_rxdma_grpid));
23876f45ec7bSml29623 
2388c1f9c6e5SSantwona Behera 	nxgep->intr_timeout = NXGE_RDC_RCR_TIMEOUT;
23896f45ec7bSml29623 	prop = param_arr[param_rxdma_intr_time].fcode_name;
23906f45ec7bSml29623 
23916f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
23926f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
23936f45ec7bSml29623 		if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2394c1f9c6e5SSantwona Behera 			nxgep->intr_timeout = prop_val[0];
23956f45ec7bSml29623 			(void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
23966f45ec7bSml29623 			    nxgep->dip, prop, prop_val, prop_len);
23976f45ec7bSml29623 		}
23986f45ec7bSml29623 		ddi_prop_free(prop_val);
23996f45ec7bSml29623 	}
2400c1f9c6e5SSantwona Behera 
2401c1f9c6e5SSantwona Behera 	nxgep->intr_threshold = NXGE_RDC_RCR_THRESHOLD;
24026f45ec7bSml29623 	prop = param_arr[param_rxdma_intr_pkts].fcode_name;
24036f45ec7bSml29623 
24046f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, prop,
24056f45ec7bSml29623 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
24066f45ec7bSml29623 		if ((prop_len > 0) && (prop_len <= p_cfgp->max_rdcs)) {
2407c1f9c6e5SSantwona Behera 			nxgep->intr_threshold = prop_val[0];
24086f45ec7bSml29623 			(void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
24096f45ec7bSml29623 			    nxgep->dip, prop, prop_val, prop_len);
24106f45ec7bSml29623 		}
24116f45ec7bSml29623 		ddi_prop_free(prop_val);
24126f45ec7bSml29623 	}
24136f45ec7bSml29623 	nxge_set_hw_dma_config(nxgep);
24146f45ec7bSml29623 
241559ac0c16Sdavemq 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config: "
241659ac0c16Sdavemq 	    "sTDC[%d] nTDC[%d] sRDC[%d] nRDC[%d]",
2417678453a8Sspeer 	    p_cfgp->tdc.start, p_cfgp->tdc.count,
241859ac0c16Sdavemq 	    p_cfgp->start_rdc, p_cfgp->max_rdcs));
241959ac0c16Sdavemq 
2420678453a8Sspeer nxge_use_cfg_dma_config_exit:
24216f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_use_cfg_dma_config"));
24226f45ec7bSml29623 }
24236f45ec7bSml29623 
2424678453a8Sspeer void
2425678453a8Sspeer nxge_get_logical_props(p_nxge_t nxgep)
2426678453a8Sspeer {
2427678453a8Sspeer 	nxge_dma_pt_cfg_t *port = &nxgep->pt_config;
2428678453a8Sspeer 	nxge_hw_pt_cfg_t *hardware;
2429678453a8Sspeer 	nxge_rdc_grp_t *group;
2430678453a8Sspeer 
2431678453a8Sspeer 	(void) memset(port, 0, sizeof (*port));
2432678453a8Sspeer 
2433da14cebeSEric Cheng 	port->mac_port = nxgep->function_num;	/* := function number */
2434678453a8Sspeer 
2435678453a8Sspeer 	/*
2436678453a8Sspeer 	 * alloc_buf_size:
2437678453a8Sspeer 	 * dead variables.
2438678453a8Sspeer 	 */
2439678453a8Sspeer 	port->rbr_size = nxge_rbr_size;
2440678453a8Sspeer 	port->rcr_size = nxge_rcr_size;
2441678453a8Sspeer 
2442678453a8Sspeer 	port->tx_dma_map = 0;	/* Transmit DMA channel bit map */
2443678453a8Sspeer 
2444678453a8Sspeer 	nxge_set_rdc_intr_property(nxgep);
2445678453a8Sspeer 
2446678453a8Sspeer 	port->rcr_full_header = NXGE_RCR_FULL_HEADER;
2447678453a8Sspeer 	port->rx_drr_weight = PT_DRR_WT_DEFAULT_10G;
2448678453a8Sspeer 
2449678453a8Sspeer 	/* ----------------------------------------------------- */
2450678453a8Sspeer 	hardware = &port->hw_config;
2451678453a8Sspeer 
2452678453a8Sspeer 	(void) memset(hardware, 0, sizeof (*hardware));
2453678453a8Sspeer 
2454678453a8Sspeer 	/*
2455678453a8Sspeer 	 * partition_id, read_write_mode:
2456678453a8Sspeer 	 * dead variables.
2457678453a8Sspeer 	 */
2458678453a8Sspeer 
2459678453a8Sspeer 	/*
2460678453a8Sspeer 	 * drr_wt, rx_full_header, *_ldg?, start_mac_entry,
2461678453a8Sspeer 	 * mac_pref, def_mac_rxdma_grpid, start_vlan, max_vlans,
2462678453a8Sspeer 	 * start_ldgs, max_ldgs, max_ldvs,
2463678453a8Sspeer 	 * vlan_pref, def_vlan_rxdma_grpid are meaningful only
2464678453a8Sspeer 	 * in the service domain.
2465678453a8Sspeer 	 */
2466678453a8Sspeer 
2467678453a8Sspeer 	group = &port->rdc_grps[0];
2468678453a8Sspeer 
2469da14cebeSEric Cheng 	group->flag = B_TRUE;	/* configured */
2470678453a8Sspeer 	group->config_method = RDC_TABLE_ENTRY_METHOD_REP;
2471da14cebeSEric Cheng 	group->port = NXGE_GET_PORT_NUM(nxgep->function_num);
2472678453a8Sspeer 
2473678453a8Sspeer 	/* HIO futures: this is still an open question. */
2474678453a8Sspeer 	hardware->max_macs = 1;
2475678453a8Sspeer }
2476678453a8Sspeer 
24776f45ec7bSml29623 static void
24786f45ec7bSml29623 nxge_use_cfg_vlan_class_config(p_nxge_t nxgep)
24796f45ec7bSml29623 {
24806f45ec7bSml29623 	uint_t vlan_cnt;
24816f45ec7bSml29623 	int *vlan_cfg_val;
24826f45ec7bSml29623 	int status;
24836f45ec7bSml29623 	p_nxge_param_t param_arr;
24846f45ec7bSml29623 	char *prop;
24856f45ec7bSml29623 
24866f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_use_cfg_vlan_config"));
24876f45ec7bSml29623 	param_arr = nxgep->param_arr;
24886f45ec7bSml29623 	prop = param_arr[param_vlan_2rdc_grp].fcode_name;
24896f45ec7bSml29623 
24906f45ec7bSml29623 	status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop,
24916f45ec7bSml29623 	    &vlan_cfg_val, &vlan_cnt);
24926f45ec7bSml29623 	if (status == DDI_PROP_SUCCESS) {
24936f45ec7bSml29623 		status = ddi_prop_update_int_array(DDI_DEV_T_NONE,
24946f45ec7bSml29623 		    nxgep->dip, prop, vlan_cfg_val, vlan_cnt);
24956f45ec7bSml29623 		ddi_prop_free(vlan_cfg_val);
24966f45ec7bSml29623 	}
24976f45ec7bSml29623 	nxge_set_hw_vlan_class_config(nxgep);
24986f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_vlan_config"));
24996f45ec7bSml29623 }
25006f45ec7bSml29623 
25016f45ec7bSml29623 static void
25026f45ec7bSml29623 nxge_use_cfg_mac_class_config(p_nxge_t nxgep)
25036f45ec7bSml29623 {
25046f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
25056f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
25066f45ec7bSml29623 	uint_t mac_cnt;
25076f45ec7bSml29623 	int *mac_cfg_val;
25086f45ec7bSml29623 	int status;
25096f45ec7bSml29623 	p_nxge_param_t param_arr;
25106f45ec7bSml29623 	char *prop;
25116f45ec7bSml29623 
25126f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_use_cfg_mac_class_config"));
25136f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
25146f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
25156f45ec7bSml29623 	p_cfgp->start_mac_entry = 0;
25166f45ec7bSml29623 	param_arr = nxgep->param_arr;
25176f45ec7bSml29623 	prop = param_arr[param_mac_2rdc_grp].fcode_name;
25186f45ec7bSml29623 
25196f45ec7bSml29623 	switch (nxgep->function_num) {
25206f45ec7bSml29623 	case 0:
25216f45ec7bSml29623 	case 1:
25226f45ec7bSml29623 		/* 10G ports */
25236f45ec7bSml29623 		p_cfgp->max_macs = NXGE_MAX_MACS_XMACS;
25246f45ec7bSml29623 		break;
25256f45ec7bSml29623 	case 2:
25266f45ec7bSml29623 	case 3:
25276f45ec7bSml29623 		/* 1G ports */
25286f45ec7bSml29623 	default:
25296f45ec7bSml29623 		p_cfgp->max_macs = NXGE_MAX_MACS_BMACS;
25306f45ec7bSml29623 		break;
25316f45ec7bSml29623 	}
25326f45ec7bSml29623 
25336f45ec7bSml29623 	p_cfgp->mac_pref = 1;
25346f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, OBP_CTL,
25356f45ec7bSml29623 	    "== nxge_use_cfg_mac_class_config: "
25366f45ec7bSml29623 	    " mac_pref bit set def_mac_rxdma_grpid %d",
25376f45ec7bSml29623 	    p_cfgp->def_mac_rxdma_grpid));
25386f45ec7bSml29623 
25396f45ec7bSml29623 	status = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop,
25406f45ec7bSml29623 	    &mac_cfg_val, &mac_cnt);
25416f45ec7bSml29623 	if (status == DDI_PROP_SUCCESS) {
25426f45ec7bSml29623 		if (mac_cnt <= p_cfgp->max_macs)
25436f45ec7bSml29623 			status = ddi_prop_update_int_array(DDI_DEV_T_NONE,
25446f45ec7bSml29623 			    nxgep->dip, prop, mac_cfg_val, mac_cnt);
25456f45ec7bSml29623 		ddi_prop_free(mac_cfg_val);
25466f45ec7bSml29623 	}
25476f45ec7bSml29623 	nxge_set_hw_mac_class_config(nxgep);
25486f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_use_cfg_mac_class_config"));
25496f45ec7bSml29623 }
25506f45ec7bSml29623 
25516f45ec7bSml29623 static void
25526f45ec7bSml29623 nxge_use_cfg_class_config(p_nxge_t nxgep)
25536f45ec7bSml29623 {
25546f45ec7bSml29623 	nxge_set_hw_class_config(nxgep);
25556f45ec7bSml29623 }
25566f45ec7bSml29623 
25576f45ec7bSml29623 static void
25586f45ec7bSml29623 nxge_set_rdc_intr_property(p_nxge_t nxgep)
25596f45ec7bSml29623 {
25606f45ec7bSml29623 	int i;
25616f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
25626f45ec7bSml29623 
25636f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_rdc_intr_property"));
25646f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
25656f45ec7bSml29623 
25666f45ec7bSml29623 	for (i = 0; i < NXGE_MAX_RDCS; i++) {
2567c1f9c6e5SSantwona Behera 		p_dma_cfgp->rcr_timeout[i] = nxgep->intr_timeout;
2568c1f9c6e5SSantwona Behera 		p_dma_cfgp->rcr_threshold[i] = nxgep->intr_threshold;
25696f45ec7bSml29623 	}
25706f45ec7bSml29623 
25716f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_rdc_intr_property"));
25726f45ec7bSml29623 }
25736f45ec7bSml29623 
25746f45ec7bSml29623 static void
25756f45ec7bSml29623 nxge_set_hw_dma_config(p_nxge_t nxgep)
25766f45ec7bSml29623 {
2577da14cebeSEric Cheng 	int			i, j, ngrps, bitmap, end, st_rdc;
25786f45ec7bSml29623 	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
25796f45ec7bSml29623 	p_nxge_hw_pt_cfg_t	p_cfgp;
25806f45ec7bSml29623 	p_nxge_rdc_grp_t	rdc_grp_p;
2581da14cebeSEric Cheng 	p_nxge_tdc_grp_t	tdc_grp_p;
2582678453a8Sspeer 	nxge_grp_t		*group;
2583da14cebeSEric Cheng 	uint8_t			nrdcs;
2584da14cebeSEric Cheng 	dc_map_t		map = 0;
25856f45ec7bSml29623 
25866f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_dma_config"));
25876f45ec7bSml29623 
25886f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
25896f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
25906f45ec7bSml29623 
2591da14cebeSEric Cheng 	switch (nxgep->niu_type) {
2592da14cebeSEric Cheng 	case NEPTUNE_4_1GC:
2593da14cebeSEric Cheng 	case NEPTUNE_2_10GF_2_1GC:
2594da14cebeSEric Cheng 	case NEPTUNE_1_10GF_3_1GC:
2595da14cebeSEric Cheng 	case NEPTUNE_1_1GC_1_10GF_2_1GC:
2596da14cebeSEric Cheng 	case NEPTUNE_2_10GF_2_1GRF:
2597da14cebeSEric Cheng 	default:
2598da14cebeSEric Cheng 		ngrps = 2;
2599da14cebeSEric Cheng 		break;
2600da14cebeSEric Cheng 	case NEPTUNE_2_10GF:
2601da14cebeSEric Cheng 	case NEPTUNE_2_1GRF:
2602da14cebeSEric Cheng 	case N2_NIU:
2603da14cebeSEric Cheng 		ngrps = 4;
2604da14cebeSEric Cheng 		break;
2605da14cebeSEric Cheng 	}
2606da14cebeSEric Cheng 
2607da14cebeSEric Cheng 	/*
2608da14cebeSEric Cheng 	 * Setup TDC groups
2609da14cebeSEric Cheng 	 */
26106f45ec7bSml29623 	bitmap = 0;
2611678453a8Sspeer 	end = p_cfgp->tdc.start + p_cfgp->tdc.owned;
2612678453a8Sspeer 	for (i = p_cfgp->tdc.start; i < end; i++) {
26136f45ec7bSml29623 		bitmap |= (1 << i);
26146f45ec7bSml29623 	}
26156f45ec7bSml29623 
2616678453a8Sspeer 	nxgep->tx_set.owned.map |= bitmap; /* Owned, & not shared. */
2617da14cebeSEric Cheng 	nxgep->tx_set.owned.count = p_cfgp->tdc.owned;
26186f45ec7bSml29623 	p_dma_cfgp->tx_dma_map = bitmap;
26196f45ec7bSml29623 
26206f45ec7bSml29623 	for (i = 0; i < ngrps; i++) {
2621da14cebeSEric Cheng 		group = (nxge_grp_t *)nxge_grp_add(nxgep,
2622da14cebeSEric Cheng 		    NXGE_TRANSMIT_GROUP);
2623da14cebeSEric Cheng 		tdc_grp_p = &p_dma_cfgp->tdc_grps[
2624da14cebeSEric Cheng 		    p_cfgp->def_mac_txdma_grpid + i];
2625da14cebeSEric Cheng 		if (i == 0)
2626da14cebeSEric Cheng 			tdc_grp_p->map = bitmap;
2627da14cebeSEric Cheng 		else
2628da14cebeSEric Cheng 			tdc_grp_p->map = 0;
2629da14cebeSEric Cheng 		/* no ring is associated with a group initially */
2630da14cebeSEric Cheng 		tdc_grp_p->start_tdc = 0;
2631da14cebeSEric Cheng 		tdc_grp_p->max_tdcs = 0;
2632da14cebeSEric Cheng 		tdc_grp_p->grp_index = group->index;
2633da14cebeSEric Cheng 	}
2634da14cebeSEric Cheng 
2635da14cebeSEric Cheng 	/*
2636da14cebeSEric Cheng 	 * Setup RDC groups
2637da14cebeSEric Cheng 	 */
2638da14cebeSEric Cheng 	st_rdc = p_cfgp->start_rdc;
2639da14cebeSEric Cheng 	for (i = 0; i < ngrps; i++) {
2640da14cebeSEric Cheng 		/*
2641da14cebeSEric Cheng 		 * All rings are associated with the default group initially
2642da14cebeSEric Cheng 		 */
2643da14cebeSEric Cheng 		if (i == 0) {
2644da14cebeSEric Cheng 			/* default group */
2645da14cebeSEric Cheng 			switch (nxgep->niu_type) {
2646da14cebeSEric Cheng 			case NEPTUNE_4_1GC:
2647da14cebeSEric Cheng 				nrdcs = rx_4_1G[nxgep->function_num];
2648da14cebeSEric Cheng 				break;
2649da14cebeSEric Cheng 			case N2_NIU:
2650da14cebeSEric Cheng 			case NEPTUNE_2_10GF:
2651da14cebeSEric Cheng 				nrdcs = rx_2_10G[nxgep->function_num];
2652da14cebeSEric Cheng 				break;
2653da14cebeSEric Cheng 			case NEPTUNE_2_10GF_2_1GC:
2654da14cebeSEric Cheng 				nrdcs = rx_2_10G_2_1G[nxgep->function_num];
2655da14cebeSEric Cheng 				break;
2656da14cebeSEric Cheng 			case NEPTUNE_1_10GF_3_1GC:
2657da14cebeSEric Cheng 				nrdcs = rx_1_10G_3_1G[nxgep->function_num];
2658da14cebeSEric Cheng 				break;
2659da14cebeSEric Cheng 			case NEPTUNE_1_1GC_1_10GF_2_1GC:
2660da14cebeSEric Cheng 				nrdcs = rx_1_1G_1_10G_2_1G[nxgep->function_num];
2661da14cebeSEric Cheng 				break;
2662da14cebeSEric Cheng 			default:
2663da14cebeSEric Cheng 				switch (nxgep->platform_type) {
2664da14cebeSEric Cheng 				case P_NEPTUNE_ALONSO:
2665da14cebeSEric Cheng 					nrdcs =
2666da14cebeSEric Cheng 					    rx_2_10G_2_1G[nxgep->function_num];
2667da14cebeSEric Cheng 					break;
2668da14cebeSEric Cheng 				default:
2669da14cebeSEric Cheng 					nrdcs = rx_4_1G[nxgep->function_num];
2670da14cebeSEric Cheng 					break;
2671da14cebeSEric Cheng 				}
2672da14cebeSEric Cheng 				break;
2673da14cebeSEric Cheng 			}
2674257bdc55SMichael Speer 
2675257bdc55SMichael Speer 			if (p_cfgp->max_rdcs < nrdcs)
2676257bdc55SMichael Speer 				nrdcs = p_cfgp->max_rdcs;
2677da14cebeSEric Cheng 		} else {
2678da14cebeSEric Cheng 			nrdcs = 0;
2679da14cebeSEric Cheng 		}
2680678453a8Sspeer 
2681678453a8Sspeer 		rdc_grp_p = &p_dma_cfgp->rdc_grps[
2682678453a8Sspeer 		    p_cfgp->def_mac_rxdma_grpid + i];
2683da14cebeSEric Cheng 		rdc_grp_p->start_rdc = st_rdc;
2684da14cebeSEric Cheng 		rdc_grp_p->max_rdcs = nrdcs;
2685678453a8Sspeer 		rdc_grp_p->def_rdc = rdc_grp_p->start_rdc;
26866f45ec7bSml29623 
26876f45ec7bSml29623 		/* default to: 0, 1, 2, 3, ...., 0, 1, 2, 3.... */
2688da14cebeSEric Cheng 		if (nrdcs != 0) {
2689da14cebeSEric Cheng 			for (j = 0; j < nrdcs; j++) {
2690da14cebeSEric Cheng 				map |= (1 << j);
2691678453a8Sspeer 			}
2692678453a8Sspeer 			map <<= rdc_grp_p->start_rdc;
2693da14cebeSEric Cheng 		} else
2694da14cebeSEric Cheng 			map = 0;
2695678453a8Sspeer 		rdc_grp_p->map = map;
2696678453a8Sspeer 
2697678453a8Sspeer 		nxgep->rx_set.owned.map |= map; /* Owned, & not shared. */
2698da14cebeSEric Cheng 		nxgep->rx_set.owned.count = nrdcs;
2699678453a8Sspeer 
2700678453a8Sspeer 		group = (nxge_grp_t *)nxge_grp_add(nxgep, NXGE_RECEIVE_GROUP);
2701678453a8Sspeer 
27026f45ec7bSml29623 		rdc_grp_p->config_method = RDC_TABLE_ENTRY_METHOD_SEQ;
2703da14cebeSEric Cheng 		rdc_grp_p->flag = B_TRUE; /* This group has been configured. */
2704da14cebeSEric Cheng 		rdc_grp_p->grp_index = group->index;
2705da14cebeSEric Cheng 		rdc_grp_p->port = NXGE_GET_PORT_NUM(nxgep->function_num);
2706da14cebeSEric Cheng 
2707da14cebeSEric Cheng 		map = 0;
27086f45ec7bSml29623 	}
2709678453a8Sspeer 
27106f45ec7bSml29623 
27116f45ec7bSml29623 	/* default RDC */
27126f45ec7bSml29623 	p_cfgp->def_rdc = p_cfgp->start_rdc;
27136f45ec7bSml29623 	nxgep->def_rdc = p_cfgp->start_rdc;
27146f45ec7bSml29623 
27156f45ec7bSml29623 	/* full 18 byte header ? */
27166f45ec7bSml29623 	p_dma_cfgp->rcr_full_header = NXGE_RCR_FULL_HEADER;
27176f45ec7bSml29623 	p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_10G;
27186f45ec7bSml29623 	if (nxgep->function_num > 1)
27196f45ec7bSml29623 		p_dma_cfgp->rx_drr_weight = PT_DRR_WT_DEFAULT_1G;
27206f45ec7bSml29623 	p_dma_cfgp->rbr_size = nxge_rbr_size;
27216f45ec7bSml29623 	p_dma_cfgp->rcr_size = nxge_rcr_size;
27226f45ec7bSml29623 
27236f45ec7bSml29623 	nxge_set_rdc_intr_property(nxgep);
27246f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_dma_config"));
27256f45ec7bSml29623 }
27266f45ec7bSml29623 
27276f45ec7bSml29623 boolean_t
27286f45ec7bSml29623 nxge_check_rxdma_port_member(p_nxge_t nxgep, uint8_t rdc)
27296f45ec7bSml29623 {
27306f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
27316f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
27326f45ec7bSml29623 	int status = B_TRUE;
27336f45ec7bSml29623 
27346f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rxdma_port_member"));
27356f45ec7bSml29623 
27366f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
27376f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
27386f45ec7bSml29623 
27396f45ec7bSml29623 	/* Receive DMA Channels */
27406f45ec7bSml29623 	if (rdc < p_cfgp->max_rdcs)
27416f45ec7bSml29623 		status = B_TRUE;
27426f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rxdma_port_member"));
27436f45ec7bSml29623 	return (status);
27446f45ec7bSml29623 }
27456f45ec7bSml29623 
27466f45ec7bSml29623 boolean_t
27476f45ec7bSml29623 nxge_check_txdma_port_member(p_nxge_t nxgep, uint8_t tdc)
27486f45ec7bSml29623 {
27496f45ec7bSml29623 	int status = B_FALSE;
27506f45ec7bSml29623 
2751678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_txdma_port_member"));
27526f45ec7bSml29623 
2753678453a8Sspeer 	if (tdc >= nxgep->pt_config.hw_config.tdc.start &&
2754678453a8Sspeer 	    tdc < nxgep->pt_config.hw_config.tdc.count)
27556f45ec7bSml29623 		status = B_TRUE;
2756678453a8Sspeer 
2757678453a8Sspeer 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_txdma_port_member"));
27586f45ec7bSml29623 	return (status);
27596f45ec7bSml29623 }
27606f45ec7bSml29623 
27616f45ec7bSml29623 boolean_t
27626f45ec7bSml29623 nxge_check_rxdma_rdcgrp_member(p_nxge_t nxgep, uint8_t rdc_grp, uint8_t rdc)
27636f45ec7bSml29623 {
27646f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
27656f45ec7bSml29623 	int status = B_TRUE;
27666f45ec7bSml29623 	p_nxge_rdc_grp_t rdc_grp_p;
27676f45ec7bSml29623 
27686f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL,
27696f45ec7bSml29623 	    " ==> nxge_check_rxdma_rdcgrp_member"));
27706f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "  nxge_check_rxdma_rdcgrp_member"
27716f45ec7bSml29623 	    " rdc  %d group %d", rdc, rdc_grp));
27726f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
27736f45ec7bSml29623 
27746f45ec7bSml29623 	rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp];
27756f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "  max  %d ", rdc_grp_p->max_rdcs));
27766f45ec7bSml29623 	if (rdc >= rdc_grp_p->max_rdcs) {
27776f45ec7bSml29623 		status = B_FALSE;
27786f45ec7bSml29623 	}
27796f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL,
27806f45ec7bSml29623 	    " <== nxge_check_rxdma_rdcgrp_member"));
27816f45ec7bSml29623 	return (status);
27826f45ec7bSml29623 }
27836f45ec7bSml29623 
27846f45ec7bSml29623 boolean_t
27856f45ec7bSml29623 nxge_check_rdcgrp_port_member(p_nxge_t nxgep, uint8_t rdc_grp)
27866f45ec7bSml29623 {
27876f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
27886f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
27896f45ec7bSml29623 	int status = B_TRUE;
27906f45ec7bSml29623 
27916f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, "==> nxge_check_rdcgrp_port_member"));
27926f45ec7bSml29623 
27936f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
27946f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
27956f45ec7bSml29623 
27966f45ec7bSml29623 	if (rdc_grp >= p_cfgp->max_rdc_grpids)
27976f45ec7bSml29623 		status = B_FALSE;
27986f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG2_CTL, " <== nxge_check_rdcgrp_port_member"));
27996f45ec7bSml29623 	return (status);
28006f45ec7bSml29623 }
28016f45ec7bSml29623 
28026f45ec7bSml29623 static void
28036f45ec7bSml29623 nxge_set_hw_vlan_class_config(p_nxge_t nxgep)
28046f45ec7bSml29623 {
28056f45ec7bSml29623 	int i;
28066f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
28076f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
28086f45ec7bSml29623 	p_nxge_param_t param_arr;
28096f45ec7bSml29623 	uint_t vlan_cnt;
28106f45ec7bSml29623 	int *vlan_cfg_val;
28116f45ec7bSml29623 	nxge_param_map_t *vmap;
28126f45ec7bSml29623 	char *prop;
28136f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
28146f45ec7bSml29623 	uint32_t good_cfg[32];
28156f45ec7bSml29623 	int good_count = 0;
28166f45ec7bSml29623 	nxge_mv_cfg_t *vlan_tbl;
28176f45ec7bSml29623 
28186f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_vlan_config"));
28196f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
28206f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
28216f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
28226f45ec7bSml29623 
28236f45ec7bSml29623 	param_arr = nxgep->param_arr;
28246f45ec7bSml29623 	prop = param_arr[param_vlan_2rdc_grp].fcode_name;
28256f45ec7bSml29623 
28266f45ec7bSml29623 	/*
28276f45ec7bSml29623 	 * By default, VLAN to RDC group mapping is disabled Need to read HW or
28286f45ec7bSml29623 	 * .conf properties to find out if mapping is required
28296f45ec7bSml29623 	 *
28306f45ec7bSml29623 	 * Format
28316f45ec7bSml29623 	 *
28326f45ec7bSml29623 	 * uint32_t array, each array entry specifying the VLAN id and the
28336f45ec7bSml29623 	 * mapping
28346f45ec7bSml29623 	 *
28356f45ec7bSml29623 	 * bit[30] = add bit[29] = remove bit[28]  = preference bits[23-16] =
28366f45ec7bSml29623 	 * rdcgrp bits[15-0] = VLAN ID ( )
28376f45ec7bSml29623 	 */
28386f45ec7bSml29623 
28396f45ec7bSml29623 	for (i = 0; i < NXGE_MAX_VLANS; i++) {
28406f45ec7bSml29623 		p_class_cfgp->vlan_tbl[i].flag = 0;
28416f45ec7bSml29623 	}
28426f45ec7bSml29623 
28436f45ec7bSml29623 	vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0];
28446f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop,
28456f45ec7bSml29623 	    &vlan_cfg_val, &vlan_cnt) == DDI_PROP_SUCCESS) {
28466f45ec7bSml29623 		for (i = 0; i < vlan_cnt; i++) {
28476f45ec7bSml29623 			vmap = (nxge_param_map_t *)&vlan_cfg_val[i];
28486f45ec7bSml29623 			if ((vmap->param_id) &&
28496f45ec7bSml29623 			    (vmap->param_id < NXGE_MAX_VLANS) &&
28506f45ec7bSml29623 			    (vmap->map_to <
28516f45ec7bSml29623 			    p_cfgp->max_rdc_grpids) &&
28526f45ec7bSml29623 			    (vmap->map_to >= (uint8_t)0)) {
28536f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG2_CTL,
28546f45ec7bSml29623 				    " nxge_vlan_config mapping"
28556f45ec7bSml29623 				    " id %d grp %d",
28566f45ec7bSml29623 				    vmap->param_id, vmap->map_to));
28576f45ec7bSml29623 				good_cfg[good_count] = vlan_cfg_val[i];
28586f45ec7bSml29623 				if (vlan_tbl[vmap->param_id].flag == 0)
28596f45ec7bSml29623 					good_count++;
28606f45ec7bSml29623 				vlan_tbl[vmap->param_id].flag = 1;
28616f45ec7bSml29623 				vlan_tbl[vmap->param_id].rdctbl =
2862678453a8Sspeer 				    vmap->map_to + p_cfgp->def_mac_rxdma_grpid;
28636f45ec7bSml29623 				vlan_tbl[vmap->param_id].mpr_npr = vmap->pref;
28646f45ec7bSml29623 			}
28656f45ec7bSml29623 		}
28666f45ec7bSml29623 		ddi_prop_free(vlan_cfg_val);
28676f45ec7bSml29623 		if (good_count != vlan_cnt) {
28686f45ec7bSml29623 			(void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
28696f45ec7bSml29623 			    nxgep->dip, prop, (int *)good_cfg, good_count);
28706f45ec7bSml29623 		}
28716f45ec7bSml29623 	}
28726f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_vlan_config"));
28736f45ec7bSml29623 }
28746f45ec7bSml29623 
28756f45ec7bSml29623 static void
28766f45ec7bSml29623 nxge_set_hw_mac_class_config(p_nxge_t nxgep)
28776f45ec7bSml29623 {
28786f45ec7bSml29623 	int i;
28796f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
28806f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
28816f45ec7bSml29623 	p_nxge_param_t param_arr;
28826f45ec7bSml29623 	uint_t mac_cnt;
28836f45ec7bSml29623 	int *mac_cfg_val;
28846f45ec7bSml29623 	nxge_param_map_t *mac_map;
28856f45ec7bSml29623 	char *prop;
28866f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
28876f45ec7bSml29623 	int good_count = 0;
28886f45ec7bSml29623 	int good_cfg[NXGE_MAX_MACS];
28896f45ec7bSml29623 	nxge_mv_cfg_t *mac_host_info;
28906f45ec7bSml29623 
28916f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "==> nxge_set_hw_mac_config"));
28926f45ec7bSml29623 
28936f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
28946f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
28956f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
28966f45ec7bSml29623 	mac_host_info = (nxge_mv_cfg_t *)&p_class_cfgp->mac_host_info[0];
28976f45ec7bSml29623 
28986f45ec7bSml29623 	param_arr = nxgep->param_arr;
28996f45ec7bSml29623 	prop = param_arr[param_mac_2rdc_grp].fcode_name;
29006f45ec7bSml29623 
29016f45ec7bSml29623 	for (i = 0; i < NXGE_MAX_MACS; i++) {
29026f45ec7bSml29623 		p_class_cfgp->mac_host_info[i].flag = 0;
29037b9fa28bSspeer 		p_class_cfgp->mac_host_info[i].rdctbl =
29047b9fa28bSspeer 		    p_cfgp->def_mac_rxdma_grpid;
29056f45ec7bSml29623 	}
29066f45ec7bSml29623 
29076f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop,
29086f45ec7bSml29623 	    &mac_cfg_val, &mac_cnt) == DDI_PROP_SUCCESS) {
29096f45ec7bSml29623 		for (i = 0; i < mac_cnt; i++) {
29106f45ec7bSml29623 			mac_map = (nxge_param_map_t *)&mac_cfg_val[i];
29116f45ec7bSml29623 			if ((mac_map->param_id < p_cfgp->max_macs) &&
29126f45ec7bSml29623 			    (mac_map->map_to <
29136f45ec7bSml29623 			    p_cfgp->max_rdc_grpids) &&
29146f45ec7bSml29623 			    (mac_map->map_to >= (uint8_t)0)) {
29156f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, CFG2_CTL,
29166f45ec7bSml29623 				    " nxge_mac_config mapping"
29176f45ec7bSml29623 				    " id %d grp %d",
29186f45ec7bSml29623 				    mac_map->param_id, mac_map->map_to));
29196f45ec7bSml29623 				mac_host_info[mac_map->param_id].mpr_npr =
2920da14cebeSEric Cheng 				    p_cfgp->mac_pref;
29216f45ec7bSml29623 				mac_host_info[mac_map->param_id].rdctbl =
29226f45ec7bSml29623 				    mac_map->map_to +
2923678453a8Sspeer 				    p_cfgp->def_mac_rxdma_grpid;
29246f45ec7bSml29623 				good_cfg[good_count] = mac_cfg_val[i];
29256f45ec7bSml29623 				if (mac_host_info[mac_map->param_id].flag == 0)
29266f45ec7bSml29623 					good_count++;
29276f45ec7bSml29623 				mac_host_info[mac_map->param_id].flag = 1;
29286f45ec7bSml29623 			}
29296f45ec7bSml29623 		}
29306f45ec7bSml29623 		ddi_prop_free(mac_cfg_val);
29316f45ec7bSml29623 		if (good_count != mac_cnt) {
29326f45ec7bSml29623 			(void) ddi_prop_update_int_array(DDI_DEV_T_NONE,
29336f45ec7bSml29623 			    nxgep->dip, prop, good_cfg, good_count);
29346f45ec7bSml29623 		}
29356f45ec7bSml29623 	}
29366f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, "<== nxge_set_hw_mac_config"));
29376f45ec7bSml29623 }
29386f45ec7bSml29623 
29396f45ec7bSml29623 static void
29406f45ec7bSml29623 nxge_set_hw_class_config(p_nxge_t nxgep)
29416f45ec7bSml29623 {
29426f45ec7bSml29623 	int i;
29436f45ec7bSml29623 	p_nxge_param_t param_arr;
29446f45ec7bSml29623 	int *int_prop_val;
29456f45ec7bSml29623 	uint32_t cfg_value;
29466f45ec7bSml29623 	char *prop;
29476f45ec7bSml29623 	p_nxge_class_pt_cfg_t p_class_cfgp;
29486f45ec7bSml29623 	int start_prop, end_prop;
29496f45ec7bSml29623 	uint_t prop_cnt;
2950c1f9c6e5SSantwona Behera 	int start_class, j = 0;
29516f45ec7bSml29623 
29526f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " ==> nxge_set_hw_class_config"));
29536f45ec7bSml29623 
29546f45ec7bSml29623 	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
29556f45ec7bSml29623 	param_arr = nxgep->param_arr;
2956c1f9c6e5SSantwona Behera 	start_prop = param_class_opt_ipv4_tcp;
29576f45ec7bSml29623 	end_prop = param_class_opt_ipv6_sctp;
2958c1f9c6e5SSantwona Behera 	start_class = TCAM_CLASS_TCP_IPV4;
29596f45ec7bSml29623 
2960c1f9c6e5SSantwona Behera 	for (i = start_prop, j = 0; i <= end_prop; i++, j++) {
29616f45ec7bSml29623 		prop = param_arr[i].fcode_name;
29626f45ec7bSml29623 		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip,
29636f45ec7bSml29623 		    0, prop, &int_prop_val,
29646f45ec7bSml29623 		    &prop_cnt) == DDI_PROP_SUCCESS) {
29656f45ec7bSml29623 			cfg_value = (uint32_t)*int_prop_val;
29666f45ec7bSml29623 			ddi_prop_free(int_prop_val);
29676f45ec7bSml29623 		} else {
29686f45ec7bSml29623 			cfg_value = (uint32_t)param_arr[i].value;
29696f45ec7bSml29623 		}
2970c1f9c6e5SSantwona Behera 		p_class_cfgp->class_cfg[start_class + j] = cfg_value;
29716f45ec7bSml29623 	}
29726f45ec7bSml29623 
29736f45ec7bSml29623 	prop = param_arr[param_h1_init_value].fcode_name;
29746f45ec7bSml29623 
29756f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop,
29766f45ec7bSml29623 	    &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) {
29776f45ec7bSml29623 		cfg_value = (uint32_t)*int_prop_val;
29786f45ec7bSml29623 		ddi_prop_free(int_prop_val);
29796f45ec7bSml29623 	} else {
29806f45ec7bSml29623 		cfg_value = (uint32_t)param_arr[param_h1_init_value].value;
29816f45ec7bSml29623 	}
29826f45ec7bSml29623 
29836f45ec7bSml29623 	p_class_cfgp->init_h1 = (uint32_t)cfg_value;
29846f45ec7bSml29623 	prop = param_arr[param_h2_init_value].fcode_name;
29856f45ec7bSml29623 
29866f45ec7bSml29623 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0, prop,
29876f45ec7bSml29623 	    &int_prop_val, &prop_cnt) == DDI_PROP_SUCCESS) {
29886f45ec7bSml29623 		cfg_value = (uint32_t)*int_prop_val;
29896f45ec7bSml29623 		ddi_prop_free(int_prop_val);
29906f45ec7bSml29623 	} else {
29916f45ec7bSml29623 		cfg_value = (uint32_t)param_arr[param_h2_init_value].value;
29926f45ec7bSml29623 	}
29936f45ec7bSml29623 
29946f45ec7bSml29623 	p_class_cfgp->init_h2 = (uint16_t)cfg_value;
29956f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, CFG_CTL, " <== nxge_set_hw_class_config"));
29966f45ec7bSml29623 }
29976f45ec7bSml29623 
29986f45ec7bSml29623 nxge_status_t
29996f45ec7bSml29623 nxge_ldgv_init_n2(p_nxge_t nxgep, int *navail_p, int *nrequired_p)
30006f45ec7bSml29623 {
3001678453a8Sspeer 	int i, maxldvs, maxldgs, nldvs;
30026f45ec7bSml29623 	int ldv, endldg;
30036f45ec7bSml29623 	uint8_t func;
30046f45ec7bSml29623 	uint8_t channel;
30056f45ec7bSml29623 	uint8_t chn_start;
30066f45ec7bSml29623 	boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE;
30076f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
30086f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
30096f45ec7bSml29623 	p_nxge_ldgv_t ldgvp;
30106f45ec7bSml29623 	p_nxge_ldg_t ldgp, ptr;
3011d7cf53fcSmisaki Miyashita 	p_nxge_ldv_t ldvp, sysldvp;
30126f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
3013678453a8Sspeer 	nxge_grp_set_t *set;
30146f45ec7bSml29623 
30156f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2"));
30166f45ec7bSml29623 	if (!*navail_p) {
30176f45ec7bSml29623 		*nrequired_p = 0;
30186f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
30196f45ec7bSml29623 		    "<== nxge_ldgv_init:no avail"));
30206f45ec7bSml29623 		return (NXGE_ERROR);
30216f45ec7bSml29623 	}
30226f45ec7bSml29623 	/*
30236f45ec7bSml29623 	 * N2/NIU: one logical device owns one logical group. and each
30246f45ec7bSml29623 	 * device/group will be assigned one vector by Hypervisor.
30256f45ec7bSml29623 	 */
30266f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
30276f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
30286f45ec7bSml29623 	maxldgs = p_cfgp->max_ldgs;
30296f45ec7bSml29623 	if (!maxldgs) {
30306f45ec7bSml29623 		/* No devices configured. */
30316f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init_n2: "
30326f45ec7bSml29623 		    "no logical groups configured."));
30336f45ec7bSml29623 		return (NXGE_ERROR);
30346f45ec7bSml29623 	} else {
30356f45ec7bSml29623 		maxldvs = maxldgs + 1;
30366f45ec7bSml29623 	}
30376f45ec7bSml29623 
30386f45ec7bSml29623 	/*
30396f45ec7bSml29623 	 * If function zero instance, it needs to handle the system and MIF
30406f45ec7bSml29623 	 * error interrupts. MIF interrupt may not be needed for N2/NIU.
30416f45ec7bSml29623 	 */
30426f45ec7bSml29623 	func = nxgep->function_num;
30436f45ec7bSml29623 	if (func == 0) {
30446f45ec7bSml29623 		own_sys_err = B_TRUE;
30456f45ec7bSml29623 		if (!p_cfgp->ser_ldvid) {
30466f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
30476f45ec7bSml29623 			    "nxge_ldgv_init_n2: func 0, ERR ID not set!"));
30486f45ec7bSml29623 		}
30496f45ec7bSml29623 		/* MIF interrupt */
30506f45ec7bSml29623 		if (!p_cfgp->mif_ldvid) {
30516f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
30526f45ec7bSml29623 			    "nxge_ldgv_init_n2: func 0, MIF ID not set!"));
30536f45ec7bSml29623 		}
30546f45ec7bSml29623 	}
30556f45ec7bSml29623 
30566f45ec7bSml29623 	/*
30576f45ec7bSml29623 	 * Assume single partition, each function owns mac.
30586f45ec7bSml29623 	 */
30596f45ec7bSml29623 	if (!nxge_use_partition)
30606f45ec7bSml29623 		own_fzc = B_TRUE;
30616f45ec7bSml29623 
30626f45ec7bSml29623 	ldgvp = nxgep->ldgvp;
30636f45ec7bSml29623 	if (ldgvp == NULL) {
30646f45ec7bSml29623 		ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP);
30656f45ec7bSml29623 		nxgep->ldgvp = ldgvp;
30666f45ec7bSml29623 		ldgvp->maxldgs = (uint8_t)maxldgs;
30676f45ec7bSml29623 		ldgvp->maxldvs = (uint8_t)maxldvs;
3068678453a8Sspeer 		ldgp = ldgvp->ldgp = KMEM_ZALLOC(
3069678453a8Sspeer 		    sizeof (nxge_ldg_t) * maxldgs, KM_SLEEP);
3070678453a8Sspeer 		ldvp = ldgvp->ldvp = KMEM_ZALLOC(
3071678453a8Sspeer 		    sizeof (nxge_ldv_t) * maxldvs, KM_SLEEP);
30726f45ec7bSml29623 	} else {
30736f45ec7bSml29623 		ldgp = ldgvp->ldgp;
30746f45ec7bSml29623 		ldvp = ldgvp->ldvp;
30756f45ec7bSml29623 	}
30766f45ec7bSml29623 
3077678453a8Sspeer 	ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs;
30786f45ec7bSml29623 	ldgvp->tmres = NXGE_TIMER_RESO;
30796f45ec7bSml29623 
30806f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
30816f45ec7bSml29623 	    "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d",
30826f45ec7bSml29623 	    maxldvs, maxldgs));
30836f45ec7bSml29623 
30846f45ec7bSml29623 	/* logical start_ldg is ldv */
30856f45ec7bSml29623 	ptr = ldgp;
30866f45ec7bSml29623 	for (i = 0; i < maxldgs; i++) {
30876f45ec7bSml29623 		ptr->func = func;
30886f45ec7bSml29623 		ptr->arm = B_TRUE;
30896f45ec7bSml29623 		ptr->vldg_index = (uint8_t)i;
30906f45ec7bSml29623 		ptr->ldg_timer = NXGE_TIMER_LDG;
30916f45ec7bSml29623 		ptr->ldg = p_cfgp->ldg[i];
30926f45ec7bSml29623 		ptr->sys_intr_handler = nxge_intr;
30936f45ec7bSml29623 		ptr->nldvs = 0;
30946f45ec7bSml29623 		ptr->ldvp = NULL;
30956f45ec7bSml29623 		ptr->nxgep = nxgep;
30966f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
30976f45ec7bSml29623 		    "==> nxge_ldgv_init_n2: maxldvs %d maxldgs %d "
30986f45ec7bSml29623 		    "ldg %d ldgptr $%p",
30996f45ec7bSml29623 		    maxldvs, maxldgs, ptr->ldg, ptr));
31006f45ec7bSml29623 		ptr++;
31016f45ec7bSml29623 	}
31026f45ec7bSml29623 
31036f45ec7bSml29623 	endldg = NXGE_INT_MAX_LDG;
31046f45ec7bSml29623 	nldvs = 0;
31056f45ec7bSml29623 	ldgvp->nldvs = 0;
31066f45ec7bSml29623 	ldgp->ldvp = NULL;
31076f45ec7bSml29623 	*nrequired_p = 0;
31086f45ec7bSml29623 
31096f45ec7bSml29623 	/*
31106f45ec7bSml29623 	 * logical device group table is organized in the following order (same
31116f45ec7bSml29623 	 * as what interrupt property has). function 0: owns MAC, MIF, error,
31126f45ec7bSml29623 	 * rx, tx. function 1: owns MAC, rx, tx.
31136f45ec7bSml29623 	 */
31146f45ec7bSml29623 
31156f45ec7bSml29623 	if (own_fzc && p_cfgp->mac_ldvid) {
31166f45ec7bSml29623 		/* Each function should own MAC interrupt */
31176f45ec7bSml29623 		ldv = p_cfgp->mac_ldvid;
31186f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
31196f45ec7bSml29623 		ldvp->is_mac = B_TRUE;
31206f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_mac_intr;
31216f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
31226f45ec7bSml29623 		ldvp->nxgep = nxgep;
31236f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
31246f45ec7bSml29623 		    "==> nxge_ldgv_init_n2(mac): maxldvs %d ldv %d "
31256f45ec7bSml29623 		    "ldg %d ldgptr $%p ldvptr $%p",
31266f45ec7bSml29623 		    maxldvs, ldv, ldgp->ldg, ldgp, ldvp));
31276f45ec7bSml29623 		nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
31286f45ec7bSml29623 		nldvs++;
31296f45ec7bSml29623 	}
31306f45ec7bSml29623 
31316f45ec7bSml29623 	if (own_fzc && p_cfgp->mif_ldvid) {
31326f45ec7bSml29623 		ldv = p_cfgp->mif_ldvid;
31336f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
31346f45ec7bSml29623 		ldvp->is_mif = B_TRUE;
31356f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_mif_intr;
31366f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
31376f45ec7bSml29623 		ldvp->nxgep = nxgep;
31386f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
31396f45ec7bSml29623 		    "==> nxge_ldgv_init_n2(mif): maxldvs %d ldv %d "
31406f45ec7bSml29623 		    "ldg %d ldgptr $%p ldvptr $%p",
31416f45ec7bSml29623 		    maxldvs, ldv, ldgp->ldg, ldgp, ldvp));
31426f45ec7bSml29623 		nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
31436f45ec7bSml29623 		nldvs++;
31446f45ec7bSml29623 	}
31456f45ec7bSml29623 
3146d7cf53fcSmisaki Miyashita 	/*
3147da14cebeSEric Cheng 	 * HW based syserr interrupt for port0, and SW based syserr interrupt
3148da14cebeSEric Cheng 	 * for port1
3149d7cf53fcSmisaki Miyashita 	 */
31506f45ec7bSml29623 	if (own_sys_err && p_cfgp->ser_ldvid) {
31516f45ec7bSml29623 		ldv = p_cfgp->ser_ldvid;
31526f45ec7bSml29623 		/*
31536f45ec7bSml29623 		 * Unmask the system interrupt states.
31546f45ec7bSml29623 		 */
31556f45ec7bSml29623 		(void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK |
31566f45ec7bSml29623 		    SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK |
31576f45ec7bSml29623 		    SYS_ERR_ZCP_MASK);
3158d7cf53fcSmisaki Miyashita 
3159d7cf53fcSmisaki Miyashita 		ldvp->use_timer = B_TRUE;
31606f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
31616f45ec7bSml29623 		ldvp->is_syserr = B_TRUE;
31626f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_syserr_intr;
31636f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
31646f45ec7bSml29623 		ldvp->nxgep = nxgep;
31656f45ec7bSml29623 		ldgvp->ldvp_syserr = ldvp;
31666f45ec7bSml29623 
31676f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
31686f45ec7bSml29623 		    "==> nxge_ldgv_init_n2(syserr): maxldvs %d ldv %d "
31696f45ec7bSml29623 		    "ldg %d ldgptr $%p ldvptr p%p",
31706f45ec7bSml29623 		    maxldvs, ldv, ldgp->ldg, ldgp, ldvp));
3171d7cf53fcSmisaki Miyashita 		nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
31726f45ec7bSml29623 		nldvs++;
3173d7cf53fcSmisaki Miyashita 	} else {
3174d7cf53fcSmisaki Miyashita 		/*
3175da14cebeSEric Cheng 		 * SW based: allocate the ldv for the syserr since the vector
3176da14cebeSEric Cheng 		 * should not be consumed for port1
3177d7cf53fcSmisaki Miyashita 		 */
3178d7cf53fcSmisaki Miyashita 		sysldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t), KM_SLEEP);
3179d7cf53fcSmisaki Miyashita 		sysldvp->use_timer = B_TRUE;
3180d7cf53fcSmisaki Miyashita 		sysldvp->ldv = NXGE_SYS_ERROR_LD;
3181d7cf53fcSmisaki Miyashita 		sysldvp->is_syserr = B_TRUE;
3182d7cf53fcSmisaki Miyashita 		sysldvp->ldv_intr_handler = nxge_syserr_intr;
3183d7cf53fcSmisaki Miyashita 		sysldvp->ldv_ldf_masks = 0;
3184d7cf53fcSmisaki Miyashita 		sysldvp->nxgep = nxgep;
3185d7cf53fcSmisaki Miyashita 		ldgvp->ldvp_syserr = sysldvp;
3186da14cebeSEric Cheng 		ldgvp->ldvp_syserr_alloced = B_TRUE;
3187d7cf53fcSmisaki Miyashita 	}
31886f45ec7bSml29623 
3189da14cebeSEric Cheng 
31906f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: "
31916f45ec7bSml29623 	    "(before rx) func %d nldvs %d navail %d nrequired %d",
31926f45ec7bSml29623 	    func, nldvs, *navail_p, *nrequired_p));
31936f45ec7bSml29623 
31946f45ec7bSml29623 	/*
31956f45ec7bSml29623 	 * Start with RDC to configure logical devices for each group.
31966f45ec7bSml29623 	 */
3197678453a8Sspeer 	chn_start = p_cfgp->ldg_chn_start;
3198678453a8Sspeer 	set = &nxgep->rx_set;
3199678453a8Sspeer 	for (channel = 0; channel < NXGE_MAX_RDCS; channel++) {
3200678453a8Sspeer 		if ((1 << channel) & set->owned.map) {
32016f45ec7bSml29623 			ldvp->is_rxdma = B_TRUE;
3202678453a8Sspeer 			ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START;
3203678453a8Sspeer 			ldvp->channel = channel;
3204678453a8Sspeer 			ldvp->vdma_index = (uint8_t)channel;
32056f45ec7bSml29623 			ldvp->ldv_intr_handler = nxge_rx_intr;
32066f45ec7bSml29623 			ldvp->ldv_ldf_masks = 0;
32076f45ec7bSml29623 			ldvp->nxgep = nxgep;
32086f45ec7bSml29623 			ldgp->ldg = p_cfgp->ldg[chn_start];
32096f45ec7bSml29623 
32106f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
32116f45ec7bSml29623 			    "==> nxge_ldgv_init_n2(rx%d): maxldvs %d ldv %d "
32126f45ec7bSml29623 			    "ldg %d ldgptr 0x%016llx ldvptr 0x%016llx",
32136f45ec7bSml29623 			    i, maxldvs, ldv, ldgp->ldg, ldgp, ldvp));
3214678453a8Sspeer 			nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv,
3215678453a8Sspeer 			    endldg, nrequired_p);
32166f45ec7bSml29623 			nldvs++;
3217678453a8Sspeer 			chn_start++;
3218678453a8Sspeer 		}
32196f45ec7bSml29623 	}
32206f45ec7bSml29623 
32216f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: "
32226f45ec7bSml29623 	    "func %d nldvs %d navail %d nrequired %d",
32236f45ec7bSml29623 	    func, nldvs, *navail_p, *nrequired_p));
32246f45ec7bSml29623 
32256f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: "
32266f45ec7bSml29623 	    "func %d nldvs %d navail %d nrequired %d ldgp 0x%llx "
32276f45ec7bSml29623 	    "ldvp 0x%llx",
32286f45ec7bSml29623 	    func, nldvs, *navail_p, *nrequired_p, ldgp, ldvp));
32296f45ec7bSml29623 	/*
32306f45ec7bSml29623 	 * Transmit DMA channels.
32316f45ec7bSml29623 	 */
3232678453a8Sspeer 	chn_start = p_cfgp->ldg_chn_start + 8;
3233678453a8Sspeer 	set = &nxgep->tx_set;
3234678453a8Sspeer 	for (channel = 0; channel < NXGE_MAX_TDCS; channel++) {
3235678453a8Sspeer 		if ((1 << channel) & set->owned.map) {
32366f45ec7bSml29623 			ldvp->is_txdma = B_TRUE;
3237678453a8Sspeer 			ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START;
3238678453a8Sspeer 			ldvp->channel = channel;
3239678453a8Sspeer 			ldvp->vdma_index = (uint8_t)channel;
32406f45ec7bSml29623 			ldvp->ldv_intr_handler = nxge_tx_intr;
32416f45ec7bSml29623 			ldvp->ldv_ldf_masks = 0;
32426f45ec7bSml29623 			ldgp->ldg = p_cfgp->ldg[chn_start];
32436f45ec7bSml29623 			ldvp->nxgep = nxgep;
32446f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
32456f45ec7bSml29623 			    "==> nxge_ldgv_init_n2(tx%d): maxldvs %d ldv %d "
3246678453a8Sspeer 			    "ldg %d ldgptr %p ldvptr %p",
3247678453a8Sspeer 			    channel, maxldvs, ldv, ldgp->ldg, ldgp, ldvp));
3248678453a8Sspeer 			nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv,
3249678453a8Sspeer 			    endldg, nrequired_p);
32506f45ec7bSml29623 			nldvs++;
3251678453a8Sspeer 			chn_start++;
3252678453a8Sspeer 		}
32536f45ec7bSml29623 	}
32546f45ec7bSml29623 
32556f45ec7bSml29623 	ldgvp->ldg_intrs = *nrequired_p;
32566f45ec7bSml29623 	ldgvp->nldvs = (uint8_t)nldvs;
32576f45ec7bSml29623 
32586f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init_n2: "
32596f45ec7bSml29623 	    "func %d nldvs %d maxgrps %d navail %d nrequired %d",
32606f45ec7bSml29623 	    func, nldvs, maxldgs, *navail_p, *nrequired_p));
32616f45ec7bSml29623 
32626f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init_n2"));
32636f45ec7bSml29623 	return (status);
32646f45ec7bSml29623 }
32656f45ec7bSml29623 
32666f45ec7bSml29623 /*
32676f45ec7bSml29623  * Interrupts related interface functions.
32686f45ec7bSml29623  */
32696f45ec7bSml29623 
32706f45ec7bSml29623 nxge_status_t
32716f45ec7bSml29623 nxge_ldgv_init(p_nxge_t nxgep, int *navail_p, int *nrequired_p)
32726f45ec7bSml29623 {
3273678453a8Sspeer 	int i, maxldvs, maxldgs, nldvs;
32746f45ec7bSml29623 	int ldv, ldg, endldg, ngrps;
32756f45ec7bSml29623 	uint8_t func;
32766f45ec7bSml29623 	uint8_t channel;
32776f45ec7bSml29623 	boolean_t own_sys_err = B_FALSE, own_fzc = B_FALSE;
32786f45ec7bSml29623 	p_nxge_dma_pt_cfg_t p_dma_cfgp;
32796f45ec7bSml29623 	p_nxge_hw_pt_cfg_t p_cfgp;
32806f45ec7bSml29623 	p_nxge_ldgv_t ldgvp;
32816f45ec7bSml29623 	p_nxge_ldg_t ldgp, ptr;
32826f45ec7bSml29623 	p_nxge_ldv_t ldvp;
3283678453a8Sspeer 	nxge_grp_set_t *set;
3284678453a8Sspeer 
32856f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
32866f45ec7bSml29623 
32876f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init"));
32886f45ec7bSml29623 	if (!*navail_p) {
32896f45ec7bSml29623 		*nrequired_p = 0;
32906f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
32916f45ec7bSml29623 		    "<== nxge_ldgv_init:no avail"));
32926f45ec7bSml29623 		return (NXGE_ERROR);
32936f45ec7bSml29623 	}
32946f45ec7bSml29623 	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
32956f45ec7bSml29623 	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
32966f45ec7bSml29623 
3297678453a8Sspeer 	nldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs;
32986f45ec7bSml29623 
32996f45ec7bSml29623 	/*
33006f45ec7bSml29623 	 * If function zero instance, it needs to handle the system error
33016f45ec7bSml29623 	 * interrupts.
33026f45ec7bSml29623 	 */
33036f45ec7bSml29623 	func = nxgep->function_num;
33046f45ec7bSml29623 	if (func == 0) {
33056f45ec7bSml29623 		nldvs++;
33066f45ec7bSml29623 		own_sys_err = B_TRUE;
33076f45ec7bSml29623 	} else {
33086f45ec7bSml29623 		/* use timer */
33096f45ec7bSml29623 		nldvs++;
33106f45ec7bSml29623 	}
33116f45ec7bSml29623 
33126f45ec7bSml29623 	/*
33136f45ec7bSml29623 	 * Assume single partition, each function owns mac.
33146f45ec7bSml29623 	 */
33156f45ec7bSml29623 	if (!nxge_use_partition) {
33166f45ec7bSml29623 		/* mac */
33176f45ec7bSml29623 		nldvs++;
33186f45ec7bSml29623 		/* MIF */
33196f45ec7bSml29623 		nldvs++;
33206f45ec7bSml29623 		own_fzc = B_TRUE;
33216f45ec7bSml29623 	}
33226f45ec7bSml29623 	maxldvs = nldvs;
33236f45ec7bSml29623 	maxldgs = p_cfgp->max_ldgs;
33246f45ec7bSml29623 	if (!maxldvs || !maxldgs) {
33256f45ec7bSml29623 		/* No devices configured. */
33266f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_init: "
33276f45ec7bSml29623 		    "no logical devices or groups configured."));
33286f45ec7bSml29623 		return (NXGE_ERROR);
33296f45ec7bSml29623 	}
33306f45ec7bSml29623 	ldgvp = nxgep->ldgvp;
33316f45ec7bSml29623 	if (ldgvp == NULL) {
33326f45ec7bSml29623 		ldgvp = KMEM_ZALLOC(sizeof (nxge_ldgv_t), KM_SLEEP);
33336f45ec7bSml29623 		nxgep->ldgvp = ldgvp;
33346f45ec7bSml29623 		ldgvp->maxldgs = (uint8_t)maxldgs;
33356f45ec7bSml29623 		ldgvp->maxldvs = (uint8_t)maxldvs;
33366f45ec7bSml29623 		ldgp = ldgvp->ldgp = KMEM_ZALLOC(sizeof (nxge_ldg_t) * maxldgs,
33376f45ec7bSml29623 		    KM_SLEEP);
33386f45ec7bSml29623 		ldvp = ldgvp->ldvp = KMEM_ZALLOC(sizeof (nxge_ldv_t) * maxldvs,
33396f45ec7bSml29623 		    KM_SLEEP);
33406f45ec7bSml29623 	}
3341678453a8Sspeer 	ldgvp->ndma_ldvs = p_cfgp->tdc.owned + p_cfgp->max_rdcs;
33426f45ec7bSml29623 	ldgvp->tmres = NXGE_TIMER_RESO;
33436f45ec7bSml29623 
33446f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
33456f45ec7bSml29623 	    "==> nxge_ldgv_init: maxldvs %d maxldgs %d nldvs %d",
33466f45ec7bSml29623 	    maxldvs, maxldgs, nldvs));
33476f45ec7bSml29623 	ldg = p_cfgp->start_ldg;
33486f45ec7bSml29623 	ptr = ldgp;
33496f45ec7bSml29623 	for (i = 0; i < maxldgs; i++) {
33506f45ec7bSml29623 		ptr->func = func;
33516f45ec7bSml29623 		ptr->arm = B_TRUE;
33526f45ec7bSml29623 		ptr->vldg_index = (uint8_t)i;
33536f45ec7bSml29623 		ptr->ldg_timer = NXGE_TIMER_LDG;
33546f45ec7bSml29623 		ptr->ldg = ldg++;
33556f45ec7bSml29623 		ptr->sys_intr_handler = nxge_intr;
33566f45ec7bSml29623 		ptr->nldvs = 0;
33576f45ec7bSml29623 		ptr->nxgep = nxgep;
33586f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
33596f45ec7bSml29623 		    "==> nxge_ldgv_init: maxldvs %d maxldgs %d ldg %d",
33606f45ec7bSml29623 		    maxldvs, maxldgs, ptr->ldg));
33616f45ec7bSml29623 		ptr++;
33626f45ec7bSml29623 	}
33636f45ec7bSml29623 
33646f45ec7bSml29623 	ldg = p_cfgp->start_ldg;
33656f45ec7bSml29623 	if (maxldgs > *navail_p) {
33666f45ec7bSml29623 		ngrps = *navail_p;
33676f45ec7bSml29623 	} else {
33686f45ec7bSml29623 		ngrps = maxldgs;
33696f45ec7bSml29623 	}
33706f45ec7bSml29623 	endldg = ldg + ngrps;
33716f45ec7bSml29623 
33726f45ec7bSml29623 	/*
33736f45ec7bSml29623 	 * Receive DMA channels.
33746f45ec7bSml29623 	 */
33756f45ec7bSml29623 	nldvs = 0;
33766f45ec7bSml29623 	ldgvp->nldvs = 0;
33776f45ec7bSml29623 	ldgp->ldvp = NULL;
33786f45ec7bSml29623 	*nrequired_p = 0;
33796f45ec7bSml29623 
33806f45ec7bSml29623 	/*
33816f45ec7bSml29623 	 * Start with RDC to configure logical devices for each group.
33826f45ec7bSml29623 	 */
3383678453a8Sspeer 	set = &nxgep->rx_set;
3384678453a8Sspeer 	for (channel = 0; channel < NXGE_MAX_RDCS; channel++) {
3385678453a8Sspeer 		if ((1 << channel) & set->owned.map) {
3386678453a8Sspeer 			/* For now, <channel & <vdma_index> are the same. */
33876f45ec7bSml29623 			ldvp->is_rxdma = B_TRUE;
3388678453a8Sspeer 			ldvp->ldv = (uint8_t)channel + NXGE_RDMA_LD_START;
3389678453a8Sspeer 			ldvp->channel = channel;
3390678453a8Sspeer 			ldvp->vdma_index = (uint8_t)channel;
33916f45ec7bSml29623 			ldvp->ldv_intr_handler = nxge_rx_intr;
33926f45ec7bSml29623 			ldvp->ldv_ldf_masks = 0;
33936f45ec7bSml29623 			ldvp->use_timer = B_FALSE;
33946f45ec7bSml29623 			ldvp->nxgep = nxgep;
3395678453a8Sspeer 			nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv,
3396678453a8Sspeer 			    endldg, nrequired_p);
33976f45ec7bSml29623 			nldvs++;
33986f45ec7bSml29623 		}
3399678453a8Sspeer 	}
34006f45ec7bSml29623 
34016f45ec7bSml29623 	/*
34026f45ec7bSml29623 	 * Transmit DMA channels.
34036f45ec7bSml29623 	 */
3404678453a8Sspeer 	set = &nxgep->tx_set;
3405678453a8Sspeer 	for (channel = 0; channel < NXGE_MAX_TDCS; channel++) {
3406678453a8Sspeer 		if ((1 << channel) & set->owned.map) {
3407678453a8Sspeer 			/* For now, <channel & <vdma_index> are the same. */
34086f45ec7bSml29623 			ldvp->is_txdma = B_TRUE;
3409678453a8Sspeer 			ldvp->ldv = (uint8_t)channel + NXGE_TDMA_LD_START;
3410678453a8Sspeer 			ldvp->channel = channel;
3411678453a8Sspeer 			ldvp->vdma_index = (uint8_t)channel;
34126f45ec7bSml29623 			ldvp->ldv_intr_handler = nxge_tx_intr;
34136f45ec7bSml29623 			ldvp->ldv_ldf_masks = 0;
34146f45ec7bSml29623 			ldvp->use_timer = B_FALSE;
34156f45ec7bSml29623 			ldvp->nxgep = nxgep;
3416678453a8Sspeer 			nxge_ldgv_setup(&ldgp, &ldvp, ldvp->ldv,
3417678453a8Sspeer 			    endldg, nrequired_p);
34186f45ec7bSml29623 			nldvs++;
34196f45ec7bSml29623 		}
3420678453a8Sspeer 	}
34216f45ec7bSml29623 
34226f45ec7bSml29623 	if (own_fzc) {
34236f45ec7bSml29623 		ldv = NXGE_MIF_LD;
34246f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
34256f45ec7bSml29623 		ldvp->is_mif = B_TRUE;
34266f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_mif_intr;
34276f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
34286f45ec7bSml29623 		ldvp->use_timer = B_FALSE;
34296f45ec7bSml29623 		ldvp->nxgep = nxgep;
34306f45ec7bSml29623 		nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
34316f45ec7bSml29623 		nldvs++;
34326f45ec7bSml29623 	}
34336f45ec7bSml29623 	/*
34346f45ec7bSml29623 	 * MAC port (function zero control)
34356f45ec7bSml29623 	 */
34366f45ec7bSml29623 	if (own_fzc) {
34376f45ec7bSml29623 		ldvp->is_mac = B_TRUE;
34386f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_mac_intr;
34396f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
34406f45ec7bSml29623 		ldv = func + NXGE_MAC_LD_START;
34416f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
34426f45ec7bSml29623 		ldvp->use_timer = B_FALSE;
34436f45ec7bSml29623 		ldvp->nxgep = nxgep;
34446f45ec7bSml29623 		nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
34456f45ec7bSml29623 		nldvs++;
34466f45ec7bSml29623 	}
34476f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: "
34486f45ec7bSml29623 	    "func %d nldvs %d navail %d nrequired %d",
34496f45ec7bSml29623 	    func, nldvs, *navail_p, *nrequired_p));
34506f45ec7bSml29623 	/*
34516f45ec7bSml29623 	 * Function 0 owns system error interrupts.
34526f45ec7bSml29623 	 */
34536f45ec7bSml29623 	ldvp->use_timer = B_TRUE;
34546f45ec7bSml29623 	if (own_sys_err) {
34556f45ec7bSml29623 		ldv = NXGE_SYS_ERROR_LD;
34566f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
34576f45ec7bSml29623 		ldvp->is_syserr = B_TRUE;
34586f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_syserr_intr;
34596f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
34606f45ec7bSml29623 		ldvp->nxgep = nxgep;
34616f45ec7bSml29623 		ldgvp->ldvp_syserr = ldvp;
34626f45ec7bSml29623 		/*
34636f45ec7bSml29623 		 * Unmask the system interrupt states.
34646f45ec7bSml29623 		 */
34656f45ec7bSml29623 		(void) nxge_fzc_sys_err_mask_set(nxgep, SYS_ERR_SMX_MASK |
34666f45ec7bSml29623 		    SYS_ERR_IPP_MASK | SYS_ERR_TXC_MASK |
34676f45ec7bSml29623 		    SYS_ERR_ZCP_MASK);
34686f45ec7bSml29623 
34696f45ec7bSml29623 		(void) nxge_ldgv_setup(&ldgp, &ldvp, ldv, endldg, nrequired_p);
34706f45ec7bSml29623 		nldvs++;
34716f45ec7bSml29623 	} else {
34726f45ec7bSml29623 		ldv = NXGE_SYS_ERROR_LD;
34736f45ec7bSml29623 		ldvp->ldv = (uint8_t)ldv;
34746f45ec7bSml29623 		ldvp->is_syserr = B_TRUE;
34756f45ec7bSml29623 		ldvp->ldv_intr_handler = nxge_syserr_intr;
34766f45ec7bSml29623 		ldvp->nxgep = nxgep;
34776f45ec7bSml29623 		ldvp->ldv_ldf_masks = 0;
34786f45ec7bSml29623 		ldgvp->ldvp_syserr = ldvp;
34796f45ec7bSml29623 	}
34806f45ec7bSml29623 
34816f45ec7bSml29623 	ldgvp->ldg_intrs = *nrequired_p;
34826f45ec7bSml29623 
34836f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_init: "
34846f45ec7bSml29623 	    "func %d nldvs %d navail %d nrequired %d",
34856f45ec7bSml29623 	    func, nldvs, *navail_p, *nrequired_p));
34866f45ec7bSml29623 
34876f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_init"));
34886f45ec7bSml29623 	return (status);
34896f45ec7bSml29623 }
34906f45ec7bSml29623 
34916f45ec7bSml29623 nxge_status_t
34926f45ec7bSml29623 nxge_ldgv_uninit(p_nxge_t nxgep)
34936f45ec7bSml29623 {
34946f45ec7bSml29623 	p_nxge_ldgv_t ldgvp;
34956f45ec7bSml29623 
34966f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_ldgv_uninit"));
34976f45ec7bSml29623 	ldgvp = nxgep->ldgvp;
34986f45ec7bSml29623 	if (ldgvp == NULL) {
34996f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "<== nxge_ldgv_uninit: "
35006f45ec7bSml29623 		    "no logical group configured."));
35016f45ec7bSml29623 		return (NXGE_OK);
35026f45ec7bSml29623 	}
3503da14cebeSEric Cheng 	if (ldgvp->ldvp_syserr_alloced == B_TRUE) {
3504d7cf53fcSmisaki Miyashita 		KMEM_FREE(ldgvp->ldvp_syserr, sizeof (nxge_ldv_t));
3505d7cf53fcSmisaki Miyashita 	}
35066f45ec7bSml29623 	if (ldgvp->ldgp) {
35076f45ec7bSml29623 		KMEM_FREE(ldgvp->ldgp, sizeof (nxge_ldg_t) * ldgvp->maxldgs);
35086f45ec7bSml29623 	}
35096f45ec7bSml29623 	if (ldgvp->ldvp) {
35106f45ec7bSml29623 		KMEM_FREE(ldgvp->ldvp, sizeof (nxge_ldv_t) * ldgvp->maxldvs);
35116f45ec7bSml29623 	}
35126f45ec7bSml29623 	KMEM_FREE(ldgvp, sizeof (nxge_ldgv_t));
35136f45ec7bSml29623 	nxgep->ldgvp = NULL;
35146f45ec7bSml29623 
35156f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_ldgv_uninit"));
35166f45ec7bSml29623 	return (NXGE_OK);
35176f45ec7bSml29623 }
35186f45ec7bSml29623 
35196f45ec7bSml29623 nxge_status_t
35206f45ec7bSml29623 nxge_intr_ldgv_init(p_nxge_t nxgep)
35216f45ec7bSml29623 {
35226f45ec7bSml29623 	nxge_status_t status = NXGE_OK;
35236f45ec7bSml29623 
35246f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_ldgv_init"));
35256f45ec7bSml29623 	/*
35266f45ec7bSml29623 	 * Configure the logical device group numbers, state vectors and
35276f45ec7bSml29623 	 * interrupt masks for each logical device.
35286f45ec7bSml29623 	 */
35296f45ec7bSml29623 	status = nxge_fzc_intr_init(nxgep);
35306f45ec7bSml29623 
35316f45ec7bSml29623 	/*
35326f45ec7bSml29623 	 * Configure logical device masks and timers.
35336f45ec7bSml29623 	 */
35346f45ec7bSml29623 	status = nxge_intr_mask_mgmt(nxgep);
35356f45ec7bSml29623 
35366f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_ldgv_init"));
35376f45ec7bSml29623 	return (status);
35386f45ec7bSml29623 }
35396f45ec7bSml29623 
35406f45ec7bSml29623 nxge_status_t
35416f45ec7bSml29623 nxge_intr_mask_mgmt(p_nxge_t nxgep)
35426f45ec7bSml29623 {
35436f45ec7bSml29623 	p_nxge_ldgv_t ldgvp;
35446f45ec7bSml29623 	p_nxge_ldg_t ldgp;
35456f45ec7bSml29623 	p_nxge_ldv_t ldvp;
35466f45ec7bSml29623 	npi_handle_t handle;
35476f45ec7bSml29623 	int i, j;
35486f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
35496f45ec7bSml29623 
35506f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_intr_mask_mgmt"));
35516f45ec7bSml29623 
35526f45ec7bSml29623 	if ((ldgvp = nxgep->ldgvp) == NULL) {
35536f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
35546f45ec7bSml29623 		    "<== nxge_intr_mask_mgmt: Null ldgvp"));
35556f45ec7bSml29623 		return (NXGE_ERROR);
35566f45ec7bSml29623 	}
35576f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
35586f45ec7bSml29623 	ldgp = ldgvp->ldgp;
35596f45ec7bSml29623 	ldvp = ldgvp->ldvp;
35606f45ec7bSml29623 	if (ldgp == NULL || ldvp == NULL) {
35616f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
35626f45ec7bSml29623 		    "<== nxge_intr_mask_mgmt: Null ldgp or ldvp"));
35636f45ec7bSml29623 		return (NXGE_ERROR);
35646f45ec7bSml29623 	}
35656f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
35666f45ec7bSml29623 	    "==> nxge_intr_mask_mgmt: # of intrs %d ", ldgvp->ldg_intrs));
35676f45ec7bSml29623 	/* Initialize masks. */
35686f45ec7bSml29623 	if (nxgep->niu_type != N2_NIU) {
35696f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
35706f45ec7bSml29623 		    "==> nxge_intr_mask_mgmt(Neptune): # intrs %d ",
35716f45ec7bSml29623 		    ldgvp->ldg_intrs));
35726f45ec7bSml29623 		for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) {
35736f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
35746f45ec7bSml29623 			    "==> nxge_intr_mask_mgmt(Neptune): # ldv %d "
35756f45ec7bSml29623 			    "in group %d", ldgp->nldvs, ldgp->ldg));
35766f45ec7bSml29623 			for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
35776f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
35786f45ec7bSml29623 				    "==> nxge_intr_mask_mgmt: set ldv # %d "
35796f45ec7bSml29623 				    "for ldg %d", ldvp->ldv, ldgp->ldg));
35806f45ec7bSml29623 				rs = npi_intr_mask_set(handle, ldvp->ldv,
35816f45ec7bSml29623 				    ldvp->ldv_ldf_masks);
35826f45ec7bSml29623 				if (rs != NPI_SUCCESS) {
35836f45ec7bSml29623 					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
35846f45ec7bSml29623 					    "<== nxge_intr_mask_mgmt: "
35856f45ec7bSml29623 					    "set mask failed "
35866f45ec7bSml29623 					    " rs 0x%x ldv %d mask 0x%x",
35876f45ec7bSml29623 					    rs, ldvp->ldv,
35886f45ec7bSml29623 					    ldvp->ldv_ldf_masks));
35896f45ec7bSml29623 					return (NXGE_ERROR | rs);
35906f45ec7bSml29623 				}
35916f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
35926f45ec7bSml29623 				    "==> nxge_intr_mask_mgmt: "
35936f45ec7bSml29623 				    "set mask OK "
35946f45ec7bSml29623 				    " rs 0x%x ldv %d mask 0x%x",
35956f45ec7bSml29623 				    rs, ldvp->ldv,
35966f45ec7bSml29623 				    ldvp->ldv_ldf_masks));
35976f45ec7bSml29623 			}
35986f45ec7bSml29623 		}
35996f45ec7bSml29623 	}
36006f45ec7bSml29623 	ldgp = ldgvp->ldgp;
36016f45ec7bSml29623 	/* Configure timer and arm bit */
36026f45ec7bSml29623 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
36036f45ec7bSml29623 		rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
36046f45ec7bSml29623 		    ldgp->arm, ldgp->ldg_timer);
36056f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
36066f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
36076f45ec7bSml29623 			    "<== nxge_intr_mask_mgmt: "
36086f45ec7bSml29623 			    "set timer failed "
36096f45ec7bSml29623 			    " rs 0x%x dg %d timer 0x%x",
36106f45ec7bSml29623 			    rs, ldgp->ldg, ldgp->ldg_timer));
36116f45ec7bSml29623 			return (NXGE_ERROR | rs);
36126f45ec7bSml29623 		}
36136f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
36146f45ec7bSml29623 		    "==> nxge_intr_mask_mgmt: "
36156f45ec7bSml29623 		    "set timer OK "
36166f45ec7bSml29623 		    " rs 0x%x ldg %d timer 0x%x",
36176f45ec7bSml29623 		    rs, ldgp->ldg, ldgp->ldg_timer));
36186f45ec7bSml29623 	}
36196f45ec7bSml29623 
36206f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_fzc_intr_mask_mgmt"));
36216f45ec7bSml29623 	return (NXGE_OK);
36226f45ec7bSml29623 }
36236f45ec7bSml29623 
36246f45ec7bSml29623 nxge_status_t
36256f45ec7bSml29623 nxge_intr_mask_mgmt_set(p_nxge_t nxgep, boolean_t on)
36266f45ec7bSml29623 {
36276f45ec7bSml29623 	p_nxge_ldgv_t ldgvp;
36286f45ec7bSml29623 	p_nxge_ldg_t ldgp;
36296f45ec7bSml29623 	p_nxge_ldv_t ldvp;
36306f45ec7bSml29623 	npi_handle_t handle;
36316f45ec7bSml29623 	int i, j;
36326f45ec7bSml29623 	npi_status_t rs = NPI_SUCCESS;
36336f45ec7bSml29623 
36346f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL,
36356f45ec7bSml29623 	    "==> nxge_intr_mask_mgmt_set (%d)", on));
36366f45ec7bSml29623 
36376f45ec7bSml29623 	if (nxgep->niu_type == N2_NIU) {
36386f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
36396f45ec7bSml29623 		    "<== nxge_intr_mask_mgmt_set (%d) not set (N2/NIU)",
36406f45ec7bSml29623 		    on));
36416f45ec7bSml29623 		return (NXGE_ERROR);
36426f45ec7bSml29623 	}
36436f45ec7bSml29623 
36446f45ec7bSml29623 	if ((ldgvp = nxgep->ldgvp) == NULL) {
36456f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
36466f45ec7bSml29623 		    "==> nxge_intr_mask_mgmt_set: Null ldgvp"));
36476f45ec7bSml29623 		return (NXGE_ERROR);
36486f45ec7bSml29623 	}
36496f45ec7bSml29623 
36506f45ec7bSml29623 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
36516f45ec7bSml29623 	ldgp = ldgvp->ldgp;
36526f45ec7bSml29623 	ldvp = ldgvp->ldvp;
36536f45ec7bSml29623 	if (ldgp == NULL || ldvp == NULL) {
36546f45ec7bSml29623 		NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
36556f45ec7bSml29623 		    "<== nxge_intr_mask_mgmt_set: Null ldgp or ldvp"));
36566f45ec7bSml29623 		return (NXGE_ERROR);
36576f45ec7bSml29623 	}
36586f45ec7bSml29623 	/* set masks. */
36596f45ec7bSml29623 	for (i = 0; i < ldgvp->ldg_intrs; i++, ldgp++) {
36606f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
36616f45ec7bSml29623 		    "==> nxge_intr_mask_mgmt_set: flag %d ldg %d"
36626f45ec7bSml29623 		    "set mask nldvs %d", on, ldgp->ldg, ldgp->nldvs));
36636f45ec7bSml29623 		for (j = 0; j < ldgp->nldvs; j++, ldvp++) {
36646f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
36656f45ec7bSml29623 			    "==> nxge_intr_mask_mgmt_set: "
36666f45ec7bSml29623 			    "for %d %d flag %d", i, j, on));
36676f45ec7bSml29623 			if (on) {
36686f45ec7bSml29623 				ldvp->ldv_ldf_masks = 0;
36696f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
36706f45ec7bSml29623 				    "==> nxge_intr_mask_mgmt_set: "
36716f45ec7bSml29623 				    "ON mask off"));
36726f45ec7bSml29623 			} else if (!on) {
36736f45ec7bSml29623 				ldvp->ldv_ldf_masks = (uint8_t)LD_IM1_MASK;
36746f45ec7bSml29623 				NXGE_DEBUG_MSG((nxgep, INT_CTL,
36756f45ec7bSml29623 				    "==> nxge_intr_mask_mgmt_set:mask on"));
36766f45ec7bSml29623 			}
36776f45ec7bSml29623 			rs = npi_intr_mask_set(handle, ldvp->ldv,
36786f45ec7bSml29623 			    ldvp->ldv_ldf_masks);
36796f45ec7bSml29623 			if (rs != NPI_SUCCESS) {
36806f45ec7bSml29623 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
36816f45ec7bSml29623 				    "==> nxge_intr_mask_mgmt_set: "
36826f45ec7bSml29623 				    "set mask failed "
36836f45ec7bSml29623 				    " rs 0x%x ldv %d mask 0x%x",
36846f45ec7bSml29623 				    rs, ldvp->ldv, ldvp->ldv_ldf_masks));
36856f45ec7bSml29623 				return (NXGE_ERROR | rs);
36866f45ec7bSml29623 			}
36876f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, INT_CTL,
36886f45ec7bSml29623 			    "==> nxge_intr_mask_mgmt_set: flag %d"
36896f45ec7bSml29623 			    "set mask OK "
36906f45ec7bSml29623 			    " ldv %d mask 0x%x",
36916f45ec7bSml29623 			    on, ldvp->ldv, ldvp->ldv_ldf_masks));
36926f45ec7bSml29623 		}
36936f45ec7bSml29623 	}
36946f45ec7bSml29623 
36956f45ec7bSml29623 	ldgp = ldgvp->ldgp;
36966f45ec7bSml29623 	/* set the arm bit */
36976f45ec7bSml29623 	for (i = 0; i < nxgep->ldgvp->ldg_intrs; i++, ldgp++) {
36986f45ec7bSml29623 		if (on && !ldgp->arm) {
36996f45ec7bSml29623 			ldgp->arm = B_TRUE;
37006f45ec7bSml29623 		} else if (!on && ldgp->arm) {
37016f45ec7bSml29623 			ldgp->arm = B_FALSE;
37026f45ec7bSml29623 		}
37036f45ec7bSml29623 		rs = npi_intr_ldg_mgmt_set(handle, ldgp->ldg,
37046f45ec7bSml29623 		    ldgp->arm, ldgp->ldg_timer);
37056f45ec7bSml29623 		if (rs != NPI_SUCCESS) {
37066f45ec7bSml29623 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
37076f45ec7bSml29623 			    "<== nxge_intr_mask_mgmt_set: "
37086f45ec7bSml29623 			    "set timer failed "
37096f45ec7bSml29623 			    " rs 0x%x ldg %d timer 0x%x",
37106f45ec7bSml29623 			    rs, ldgp->ldg, ldgp->ldg_timer));
37116f45ec7bSml29623 			return (NXGE_ERROR | rs);
37126f45ec7bSml29623 		}
37136f45ec7bSml29623 		NXGE_DEBUG_MSG((nxgep, INT_CTL,
37146f45ec7bSml29623 		    "==> nxge_intr_mask_mgmt_set: OK (flag %d) "
37156f45ec7bSml29623 		    "set timer "
37166f45ec7bSml29623 		    " ldg %d timer 0x%x",
37176f45ec7bSml29623 		    on, ldgp->ldg, ldgp->ldg_timer));
37186f45ec7bSml29623 	}
37196f45ec7bSml29623 
37206f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_intr_mask_mgmt_set"));
37216f45ec7bSml29623 	return (NXGE_OK);
37226f45ec7bSml29623 }
37236f45ec7bSml29623 
37246f45ec7bSml29623 static nxge_status_t
37256f45ec7bSml29623 nxge_get_mac_addr_properties(p_nxge_t nxgep)
37266f45ec7bSml29623 {
372759ac0c16Sdavemq #if defined(_BIG_ENDIAN)
37286f45ec7bSml29623 	uchar_t *prop_val;
37296f45ec7bSml29623 	uint_t prop_len;
373059ac0c16Sdavemq 	uint_t j;
373159ac0c16Sdavemq #endif
37326f45ec7bSml29623 	uint_t i;
37336f45ec7bSml29623 	uint8_t func_num;
373459ac0c16Sdavemq 	boolean_t compute_macs = B_TRUE;
37356f45ec7bSml29623 
37366f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_mac_addr_properties "));
37376f45ec7bSml29623 
37386f45ec7bSml29623 #if defined(_BIG_ENDIAN)
37396f45ec7bSml29623 	/*
37406f45ec7bSml29623 	 * Get the ethernet address.
37416f45ec7bSml29623 	 */
37426f45ec7bSml29623 	(void) localetheraddr((struct ether_addr *)NULL, &nxgep->ouraddr);
37436f45ec7bSml29623 
37446f45ec7bSml29623 	/*
37456f45ec7bSml29623 	 * Check if it is an adapter with its own local mac address If it is
37466f45ec7bSml29623 	 * present, override the system mac address.
37476f45ec7bSml29623 	 */
37486f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
37496f45ec7bSml29623 	    "local-mac-address", &prop_val,
37506f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
37516f45ec7bSml29623 		if (prop_len == ETHERADDRL) {
37526f45ec7bSml29623 			nxgep->factaddr = *(p_ether_addr_t)prop_val;
37536f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, DDI_CTL, "Local mac address = "
37546f45ec7bSml29623 			    "%02x:%02x:%02x:%02x:%02x:%02x",
37556f45ec7bSml29623 			    prop_val[0], prop_val[1], prop_val[2],
37566f45ec7bSml29623 			    prop_val[3], prop_val[4], prop_val[5]));
37576f45ec7bSml29623 		}
37586f45ec7bSml29623 		ddi_prop_free(prop_val);
37596f45ec7bSml29623 	}
37606f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
37616f45ec7bSml29623 	    "local-mac-address?", &prop_val,
37626f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
37636f45ec7bSml29623 		if (strncmp("true", (caddr_t)prop_val, (size_t)prop_len) == 0) {
37646f45ec7bSml29623 			nxgep->ouraddr = nxgep->factaddr;
37656f45ec7bSml29623 			NXGE_DEBUG_MSG((nxgep, DDI_CTL,
37666f45ec7bSml29623 			    "Using local MAC address"));
37676f45ec7bSml29623 		}
37686f45ec7bSml29623 		ddi_prop_free(prop_val);
37696f45ec7bSml29623 	} else {
37706f45ec7bSml29623 		nxgep->ouraddr = nxgep->factaddr;
37716f45ec7bSml29623 	}
37726f45ec7bSml29623 
37732e59129aSraghus 	if ((!nxgep->vpd_info.present) ||
377459ac0c16Sdavemq 	    (nxge_is_valid_local_mac(nxgep->factaddr)))
377556d930aeSspeer 		goto got_mac_addr;
377656d930aeSspeer 
377756d930aeSspeer 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "nxge_get_mac_addr_properties: "
377856d930aeSspeer 	    "MAC address from properties is not valid...reading from PROM"));
377956d930aeSspeer 
378056d930aeSspeer #endif
378156d930aeSspeer 	if (!nxgep->vpd_info.ver_valid) {
378256d930aeSspeer 		(void) nxge_espc_mac_addrs_get(nxgep);
378356d930aeSspeer 		if (!nxge_is_valid_local_mac(nxgep->factaddr)) {
37842e59129aSraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get "
37852e59129aSraghus 			    "MAC address"));
378656d930aeSspeer 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
378756d930aeSspeer 			    "[%s] invalid...please update",
378856d930aeSspeer 			    nxgep->vpd_info.ver));
378956d930aeSspeer 			return (NXGE_ERROR);
379056d930aeSspeer 		}
379156d930aeSspeer 		nxgep->ouraddr = nxgep->factaddr;
379256d930aeSspeer 		goto got_mac_addr;
379356d930aeSspeer 	}
379456d930aeSspeer 	/*
379556d930aeSspeer 	 * First get the MAC address from the info in the VPD data read
379656d930aeSspeer 	 * from the EEPROM.
379756d930aeSspeer 	 */
379856d930aeSspeer 	nxge_espc_get_next_mac_addr(nxgep->vpd_info.mac_addr,
379959ac0c16Sdavemq 	    nxgep->function_num, &nxgep->factaddr);
380056d930aeSspeer 
380156d930aeSspeer 	if (!nxge_is_valid_local_mac(nxgep->factaddr)) {
380256d930aeSspeer 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
380356d930aeSspeer 		    "nxge_get_mac_addr_properties: "
380456d930aeSspeer 		    "MAC address in EEPROM VPD data not valid"
380556d930aeSspeer 		    "...reading from NCR registers"));
380656d930aeSspeer 		(void) nxge_espc_mac_addrs_get(nxgep);
380756d930aeSspeer 		if (!nxge_is_valid_local_mac(nxgep->factaddr)) {
38082e59129aSraghus 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Failed to get "
38092e59129aSraghus 			    "MAC address"));
381056d930aeSspeer 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "EEPROM version "
381156d930aeSspeer 			    "[%s] invalid...please update",
381256d930aeSspeer 			    nxgep->vpd_info.ver));
381356d930aeSspeer 			return (NXGE_ERROR);
381456d930aeSspeer 		}
381556d930aeSspeer 	}
381656d930aeSspeer 
381756d930aeSspeer 	nxgep->ouraddr = nxgep->factaddr;
381856d930aeSspeer 
381956d930aeSspeer got_mac_addr:
38206f45ec7bSml29623 	func_num = nxgep->function_num;
38216f45ec7bSml29623 
38226f45ec7bSml29623 	/*
382359ac0c16Sdavemq 	 * Note: mac-addresses property is the list of mac addresses for a
382459ac0c16Sdavemq 	 * port. NXGE_MAX_MMAC_ADDRS is the total number of MAC addresses
382559ac0c16Sdavemq 	 * allocated for a board.
38266f45ec7bSml29623 	 */
382759ac0c16Sdavemq 	nxgep->nxge_mmac_info.total_factory_macs = NXGE_MAX_MMAC_ADDRS;
38286f45ec7bSml29623 
382959ac0c16Sdavemq #if defined(_BIG_ENDIAN)
38306f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
383159ac0c16Sdavemq 	    "mac-addresses", &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
38326f45ec7bSml29623 		/*
38336f45ec7bSml29623 		 * XAUI may have up to 18 MACs, more than the XMAC can
38346f45ec7bSml29623 		 * use (1 unique MAC plus 16 alternate MACs)
38356f45ec7bSml29623 		 */
383659ac0c16Sdavemq 		nxgep->nxge_mmac_info.num_factory_mmac =
383759ac0c16Sdavemq 		    prop_len / ETHERADDRL - 1;
38386f45ec7bSml29623 		if (nxgep->nxge_mmac_info.num_factory_mmac >
38396f45ec7bSml29623 		    XMAC_MAX_ALT_ADDR_ENTRY) {
38406f45ec7bSml29623 			nxgep->nxge_mmac_info.num_factory_mmac =
38416f45ec7bSml29623 			    XMAC_MAX_ALT_ADDR_ENTRY;
38426f45ec7bSml29623 		}
384359ac0c16Sdavemq 
384459ac0c16Sdavemq 		for (i = 1; i <= nxgep->nxge_mmac_info.num_factory_mmac; i++) {
384559ac0c16Sdavemq 			for (j = 0; j < ETHERADDRL; j++) {
384659ac0c16Sdavemq 				nxgep->nxge_mmac_info.factory_mac_pool[i][j] =
384759ac0c16Sdavemq 				    *(prop_val + (i * ETHERADDRL) + j);
38486f45ec7bSml29623 			}
384959ac0c16Sdavemq 			NXGE_DEBUG_MSG((nxgep, DDI_CTL,
385059ac0c16Sdavemq 			    "nxge_get_mac_addr_properties: Alt mac[%d] from "
385159ac0c16Sdavemq 			    "mac-addresses property[%2x:%2x:%2x:%2x:%2x:%2x]",
385259ac0c16Sdavemq 			    i, nxgep->nxge_mmac_info.factory_mac_pool[i][0],
385359ac0c16Sdavemq 			    nxgep->nxge_mmac_info.factory_mac_pool[i][1],
385459ac0c16Sdavemq 			    nxgep->nxge_mmac_info.factory_mac_pool[i][2],
385559ac0c16Sdavemq 			    nxgep->nxge_mmac_info.factory_mac_pool[i][3],
385659ac0c16Sdavemq 			    nxgep->nxge_mmac_info.factory_mac_pool[i][4],
385759ac0c16Sdavemq 			    nxgep->nxge_mmac_info.factory_mac_pool[i][5]));
385859ac0c16Sdavemq 		}
385959ac0c16Sdavemq 
386059ac0c16Sdavemq 		compute_macs = B_FALSE;
386159ac0c16Sdavemq 		ddi_prop_free(prop_val);
386259ac0c16Sdavemq 		goto got_mmac_info;
386359ac0c16Sdavemq 	}
386459ac0c16Sdavemq #endif
38656f45ec7bSml29623 	/*
38666f45ec7bSml29623 	 * total_factory_macs = 32
38676f45ec7bSml29623 	 * num_factory_mmac = (32 >> (nports/2)) - 1
38686f45ec7bSml29623 	 * So if nports = 4, then num_factory_mmac =  7
38696f45ec7bSml29623 	 *    if nports = 2, then num_factory_mmac = 15
38706f45ec7bSml29623 	 */
387159ac0c16Sdavemq 	nxgep->nxge_mmac_info.num_factory_mmac =
387259ac0c16Sdavemq 	    ((nxgep->nxge_mmac_info.total_factory_macs >>
38736f45ec7bSml29623 	    (nxgep->nports >> 1))) - 1;
387456d930aeSspeer 
387559ac0c16Sdavemq got_mmac_info:
387659ac0c16Sdavemq 
387756d930aeSspeer 	if ((nxgep->function_num < 2) &&
387856d930aeSspeer 	    (nxgep->nxge_mmac_info.num_factory_mmac >
387956d930aeSspeer 	    XMAC_MAX_ALT_ADDR_ENTRY)) {
388056d930aeSspeer 		nxgep->nxge_mmac_info.num_factory_mmac =
388156d930aeSspeer 		    XMAC_MAX_ALT_ADDR_ENTRY;
388256d930aeSspeer 	} else if ((nxgep->function_num > 1) &&
388356d930aeSspeer 	    (nxgep->nxge_mmac_info.num_factory_mmac >
388456d930aeSspeer 	    BMAC_MAX_ALT_ADDR_ENTRY)) {
388556d930aeSspeer 		nxgep->nxge_mmac_info.num_factory_mmac =
388656d930aeSspeer 		    BMAC_MAX_ALT_ADDR_ENTRY;
388756d930aeSspeer 	}
388856d930aeSspeer 
38896f45ec7bSml29623 	for (i = 0; i <= nxgep->nxge_mmac_info.num_mmac; i++) {
38906f45ec7bSml29623 		(void) npi_mac_altaddr_disable(nxgep->npi_handle,
38916f45ec7bSml29623 		    NXGE_GET_PORT_NUM(func_num), i);
38926f45ec7bSml29623 	}
38936f45ec7bSml29623 
389459ac0c16Sdavemq 	(void) nxge_init_mmac(nxgep, compute_macs);
38956f45ec7bSml29623 	return (NXGE_OK);
38966f45ec7bSml29623 }
38976f45ec7bSml29623 
38986f45ec7bSml29623 void
38996f45ec7bSml29623 nxge_get_xcvr_properties(p_nxge_t nxgep)
39006f45ec7bSml29623 {
39016f45ec7bSml29623 	uchar_t *prop_val;
39026f45ec7bSml29623 	uint_t prop_len;
39036f45ec7bSml29623 
39046f45ec7bSml29623 	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_get_xcvr_properties"));
39056f45ec7bSml29623 
39066f45ec7bSml29623 	/*
39076f45ec7bSml29623 	 * Read the type of physical layer interface being used.
39086f45ec7bSml29623 	 */
39096f45ec7bSml29623 	nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
39106f45ec7bSml29623 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
39116f45ec7bSml29623 	    "phy-type", &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
39126f45ec7bSml29623 		if (strncmp("pcs", (caddr_t)prop_val,
39136f45ec7bSml29623 		    (size_t)prop_len) == 0) {
39146f45ec7bSml29623 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
39156f45ec7bSml29623 		} else {
39166f45ec7bSml29623 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
39176f45ec7bSml29623 		}
39186f45ec7bSml29623 		ddi_prop_free(prop_val);
39196f45ec7bSml29623 	} else if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, nxgep->dip, 0,
39206f45ec7bSml29623 	    "phy-interface", &prop_val,
39216f45ec7bSml29623 	    &prop_len) == DDI_PROP_SUCCESS) {
39226f45ec7bSml29623 		if (strncmp("pcs", (caddr_t)prop_val, (size_t)prop_len) == 0) {
39236f45ec7bSml29623 			nxgep->statsp->mac_stats.xcvr_inuse = PCS_XCVR;
39246f45ec7bSml29623 		} else {
39256f45ec7bSml29623 			nxgep->statsp->mac_stats.xcvr_inuse = INT_MII_XCVR;
39266f45ec7bSml29623 		}
39276f45ec7bSml29623 		ddi_prop_free(prop_val);
39286f45ec7bSml29623 	}
39296f45ec7bSml29623 }
39306f45ec7bSml29623 
39316f45ec7bSml29623 /*
39326f45ec7bSml29623  * Static functions start here.
39336f45ec7bSml29623  */
39346f45ec7bSml29623 
39356f45ec7bSml29623 static void
39366f45ec7bSml29623 nxge_ldgv_setup(p_nxge_ldg_t *ldgp, p_nxge_ldv_t *ldvp, uint8_t ldv,
39376f45ec7bSml29623 	uint8_t endldg, int *ngrps)
39386f45ec7bSml29623 {
39396f45ec7bSml29623 	NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup"));
39406f45ec7bSml29623 	/* Assign the group number for each device. */
39416f45ec7bSml29623 	(*ldvp)->ldg_assigned = (*ldgp)->ldg;
39426f45ec7bSml29623 	(*ldvp)->ldgp = *ldgp;
39436f45ec7bSml29623 	(*ldvp)->ldv = ldv;
39446f45ec7bSml29623 
39456f45ec7bSml29623 	NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: "
39466f45ec7bSml29623 	    "ldv %d endldg %d ldg %d, ldvp $%p",
39476f45ec7bSml29623 	    ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp));
39486f45ec7bSml29623 
39496f45ec7bSml29623 	(*ldgp)->nldvs++;
39506f45ec7bSml29623 	if ((*ldgp)->ldg == (endldg - 1)) {
39516f45ec7bSml29623 		if ((*ldgp)->ldvp == NULL) {
39526f45ec7bSml29623 			(*ldgp)->ldvp = *ldvp;
39536f45ec7bSml29623 			*ngrps += 1;
39546f45ec7bSml29623 			NXGE_DEBUG_MSG((NULL, INT_CTL,
39556f45ec7bSml29623 			    "==> nxge_ldgv_setup: ngrps %d", *ngrps));
39566f45ec7bSml29623 		}
39576f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, INT_CTL,
39586f45ec7bSml29623 		    "==> nxge_ldgv_setup: ldvp $%p ngrps %d",
39596f45ec7bSml29623 		    *ldvp, *ngrps));
39606f45ec7bSml29623 		++*ldvp;
39616f45ec7bSml29623 	} else {
39626f45ec7bSml29623 		(*ldgp)->ldvp = *ldvp;
39636f45ec7bSml29623 		*ngrps += 1;
39646f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup(done): "
39656f45ec7bSml29623 		    "ldv %d endldg %d ldg %d, ldvp $%p",
39666f45ec7bSml29623 		    ldv, endldg, (*ldgp)->ldg, (*ldgp)->ldvp));
3967*2bc98732SRichard Lowe 		++*ldvp;
3968*2bc98732SRichard Lowe 		++*ldgp;
39696f45ec7bSml29623 		NXGE_DEBUG_MSG((NULL, INT_CTL,
39706f45ec7bSml29623 		    "==> nxge_ldgv_setup: new ngrps %d", *ngrps));
39716f45ec7bSml29623 	}
39726f45ec7bSml29623 
39736f45ec7bSml29623 	NXGE_DEBUG_MSG((NULL, INT_CTL, "==> nxge_ldgv_setup: "
39746f45ec7bSml29623 	    "ldv %d ldvp $%p endldg %d ngrps %d",
39756f45ec7bSml29623 	    ldv, ldvp, endldg, *ngrps));
39766f45ec7bSml29623 
39776f45ec7bSml29623 	NXGE_DEBUG_MSG((NULL, INT_CTL, "<== nxge_ldgv_setup"));
39786f45ec7bSml29623 }
39796f45ec7bSml29623 
39806f45ec7bSml29623 /*
39816f45ec7bSml29623  * Note: This function assumes the following distribution of mac
39826f45ec7bSml29623  * addresses among 4 ports in neptune:
39836f45ec7bSml29623  *
39846f45ec7bSml29623  *      -------------
39856f45ec7bSml29623  *    0|            |0 - local-mac-address for fn 0
39866f45ec7bSml29623  *      -------------
39876f45ec7bSml29623  *    1|            |1 - local-mac-address for fn 1
39886f45ec7bSml29623  *      -------------
39896f45ec7bSml29623  *    2|            |2 - local-mac-address for fn 2
39906f45ec7bSml29623  *      -------------
39916f45ec7bSml29623  *    3|            |3 - local-mac-address for fn 3
39926f45ec7bSml29623  *      -------------
39936f45ec7bSml29623  *     |            |4 - Start of alt. mac addr. for fn 0
39946f45ec7bSml29623  *     |            |
39956f45ec7bSml29623  *     |            |
39966f45ec7bSml29623  *     |            |10
39976f45ec7bSml29623  *     --------------
39986f45ec7bSml29623  *     |            |11 - Start of alt. mac addr. for fn 1
39996f45ec7bSml29623  *     |            |
40006f45ec7bSml29623  *     |            |
40016f45ec7bSml29623  *     |            |17
40026f45ec7bSml29623  *     --------------
40036f45ec7bSml29623  *     |            |18 - Start of alt. mac addr. for fn 2
40046f45ec7bSml29623  *     |            |
40056f45ec7bSml29623  *     |            |
40066f45ec7bSml29623  *     |            |24
40076f45ec7bSml29623  *     --------------
40086f45ec7bSml29623  *     |            |25 - Start of alt. mac addr. for fn 3
40096f45ec7bSml29623  *     |            |
40106f45ec7bSml29623  *     |            |
40116f45ec7bSml29623  *     |            |31
40126f45ec7bSml29623  *     --------------
40136f45ec7bSml29623  *
40146f45ec7bSml29623  * For N2/NIU the mac addresses is from XAUI card.
401559ac0c16Sdavemq  *
401659ac0c16Sdavemq  * When 'compute_addrs' is true, the alternate mac addresses are computed
401759ac0c16Sdavemq  * using the unique mac address as base. Otherwise the alternate addresses
401859ac0c16Sdavemq  * are assigned from the list read off the 'mac-addresses' property.
40196f45ec7bSml29623  */
40206f45ec7bSml29623 
40216f45ec7bSml29623 static void
402259ac0c16Sdavemq nxge_init_mmac(p_nxge_t nxgep, boolean_t compute_addrs)
40236f45ec7bSml29623 {
40246f45ec7bSml29623 	int slot;
40256f45ec7bSml29623 	uint8_t func_num;
40266f45ec7bSml29623 	uint16_t *base_mmac_addr;
40276f45ec7bSml29623 	uint32_t alt_mac_ls4b;
40286f45ec7bSml29623 	uint16_t *mmac_addr;
40296f45ec7bSml29623 	uint32_t base_mac_ls4b; /* least significant 4 bytes */
40306f45ec7bSml29623 	nxge_mmac_t *mmac_info;
40316f45ec7bSml29623 	npi_mac_addr_t mac_addr;
40326f45ec7bSml29623 
40336f45ec7bSml29623 	func_num = nxgep->function_num;
40346f45ec7bSml29623 	base_mmac_addr = (uint16_t *)&nxgep->factaddr;
40356f45ec7bSml29623 	mmac_info = (nxge_mmac_t *)&nxgep->nxge_mmac_info;
40366f45ec7bSml29623 
403759ac0c16Sdavemq 	if (compute_addrs) {
40386f45ec7bSml29623 		base_mac_ls4b = ((uint32_t)base_mmac_addr[1]) << 16 |
40396f45ec7bSml29623 		    base_mmac_addr[2];
40406f45ec7bSml29623 
40416f45ec7bSml29623 		if (nxgep->niu_type == N2_NIU) {
404259ac0c16Sdavemq 			/* ls4b of 1st altmac */
404359ac0c16Sdavemq 			alt_mac_ls4b = base_mac_ls4b + 1;
40446f45ec7bSml29623 		} else {			/* Neptune */
404559ac0c16Sdavemq 			alt_mac_ls4b = base_mac_ls4b +
404659ac0c16Sdavemq 			    (nxgep->nports - func_num) +
404759ac0c16Sdavemq 			    (func_num * (mmac_info->num_factory_mmac));
404859ac0c16Sdavemq 		}
40496f45ec7bSml29623 	}
40506f45ec7bSml29623 
40516f45ec7bSml29623 	/* Set flags for unique MAC */
40526f45ec7bSml29623 	mmac_info->mac_pool[0].flags |= MMAC_SLOT_USED | MMAC_VENDOR_ADDR;
40536f45ec7bSml29623 
40546f45ec7bSml29623 	/* Clear flags of all alternate MAC slots */
40556f45ec7bSml29623 	for (slot = 1; slot <= mmac_info->num_mmac; slot++) {
40566f45ec7bSml29623 		if (slot <= mmac_info->num_factory_mmac)
40576f45ec7bSml29623 			mmac_info->mac_pool[slot].flags = MMAC_VENDOR_ADDR;
40586f45ec7bSml29623 		else
40596f45ec7bSml29623 			mmac_info->mac_pool[slot].flags = 0;
40606f45ec7bSml29623 	}
40616f45ec7bSml29623 
40626f45ec7bSml29623 	/* Generate and store factory alternate MACs */
40636f45ec7bSml29623 	for (slot = 1; slot <= mmac_info->num_factory_mmac; slot++) {
40646f45ec7bSml29623 		mmac_addr = (uint16_t *)&mmac_info->factory_mac_pool[slot];
406559ac0c16Sdavemq 		if (compute_addrs) {
40666f45ec7bSml29623 			mmac_addr[0] = base_mmac_addr[0];
40676f45ec7bSml29623 			mac_addr.w2 = mmac_addr[0];
40686f45ec7bSml29623 
40696f45ec7bSml29623 			mmac_addr[1] = (alt_mac_ls4b >> 16) & 0x0FFFF;
40706f45ec7bSml29623 			mac_addr.w1 = mmac_addr[1];
40716f45ec7bSml29623 
40726f45ec7bSml29623 			mmac_addr[2] = alt_mac_ls4b & 0x0FFFF;
40736f45ec7bSml29623 			mac_addr.w0 = mmac_addr[2];
407459ac0c16Sdavemq 
407559ac0c16Sdavemq 			alt_mac_ls4b++;
407659ac0c16Sdavemq 		} else {
407759ac0c16Sdavemq 			mac_addr.w2 = mmac_addr[0];
407859ac0c16Sdavemq 			mac_addr.w1 = mmac_addr[1];
407959ac0c16Sdavemq 			mac_addr.w0 = mmac_addr[2];
408059ac0c16Sdavemq 		}
408159ac0c16Sdavemq 
408259ac0c16Sdavemq 		NXGE_DEBUG_MSG((nxgep, DDI_CTL,
408359ac0c16Sdavemq 		    "mac_pool_addr[%2x:%2x:%2x:%2x:%2x:%2x] npi_addr[%x%x%x]",
408459ac0c16Sdavemq 		    mmac_info->factory_mac_pool[slot][0],
408559ac0c16Sdavemq 		    mmac_info->factory_mac_pool[slot][1],
408659ac0c16Sdavemq 		    mmac_info->factory_mac_pool[slot][2],
408759ac0c16Sdavemq 		    mmac_info->factory_mac_pool[slot][3],
408859ac0c16Sdavemq 		    mmac_info->factory_mac_pool[slot][4],
408959ac0c16Sdavemq 		    mmac_info->factory_mac_pool[slot][5],
409059ac0c16Sdavemq 		    mac_addr.w0, mac_addr.w1, mac_addr.w2));
40916f45ec7bSml29623 		/*
409259ac0c16Sdavemq 		 * slot minus 1 because npi_mac_altaddr_entry expects 0
40936f45ec7bSml29623 		 * for the first alternate mac address.
40946f45ec7bSml29623 		 */
40956f45ec7bSml29623 		(void) npi_mac_altaddr_entry(nxgep->npi_handle, OP_SET,
40966f45ec7bSml29623 		    NXGE_GET_PORT_NUM(func_num), slot - 1, &mac_addr);
40976f45ec7bSml29623 	}
40986f45ec7bSml29623 	/* Initialize the first two parameters for mmac kstat */
40996f45ec7bSml29623 	nxgep->statsp->mmac_stats.mmac_max_cnt = mmac_info->num_mmac;
41006f45ec7bSml29623 	nxgep->statsp->mmac_stats.mmac_avail_cnt = mmac_info->num_mmac;
41016f45ec7bSml29623 }
4102da14cebeSEric Cheng 
4103da14cebeSEric Cheng /*
4104da14cebeSEric Cheng  * Convert an RDC group index into a port ring index.  That is, map
4105da14cebeSEric Cheng  * <groupid> to an index into nxgep->rx_ring_handles.
4106da14cebeSEric Cheng  * (group ring index -> port ring index)
4107da14cebeSEric Cheng  */
4108da14cebeSEric Cheng int
4109da14cebeSEric Cheng nxge_get_rxring_index(p_nxge_t nxgep, int groupid, int ringidx)
4110da14cebeSEric Cheng {
4111da14cebeSEric Cheng 	int			i;
4112da14cebeSEric Cheng 	int			index = 0;
4113da14cebeSEric Cheng 	p_nxge_rdc_grp_t	rdc_grp_p;
4114da14cebeSEric Cheng 	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
4115da14cebeSEric Cheng 	p_nxge_hw_pt_cfg_t	p_cfgp;
4116da14cebeSEric Cheng 
4117da14cebeSEric Cheng 	p_dma_cfgp = &nxgep->pt_config;
4118da14cebeSEric Cheng 	p_cfgp = &p_dma_cfgp->hw_config;
4119da14cebeSEric Cheng 
412063f531d1SSriharsha Basavapatna 	if (isLDOMguest(nxgep))
412163f531d1SSriharsha Basavapatna 		return (ringidx);
412263f531d1SSriharsha Basavapatna 
4123da14cebeSEric Cheng 	for (i = 0; i < groupid; i++) {
4124da14cebeSEric Cheng 		rdc_grp_p =
4125da14cebeSEric Cheng 		    &p_dma_cfgp->rdc_grps[p_cfgp->def_mac_rxdma_grpid + i];
4126da14cebeSEric Cheng 		index += rdc_grp_p->max_rdcs;
4127da14cebeSEric Cheng 	}
4128da14cebeSEric Cheng 
4129da14cebeSEric Cheng 	return (index + ringidx);
4130da14cebeSEric Cheng }
4131