144961713Sgirish /*
244961713Sgirish  * CDDL HEADER START
344961713Sgirish  *
444961713Sgirish  * The contents of this file are subject to the terms of the
544961713Sgirish  * Common Development and Distribution License (the "License").
644961713Sgirish  * You may not use this file except in compliance with the License.
744961713Sgirish  *
844961713Sgirish  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
944961713Sgirish  * or http://www.opensolaris.org/os/licensing.
1044961713Sgirish  * See the License for the specific language governing permissions
1144961713Sgirish  * and limitations under the License.
1244961713Sgirish  *
1344961713Sgirish  * When distributing Covered Code, include this CDDL HEADER in each
1444961713Sgirish  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1544961713Sgirish  * If applicable, add the following below this CDDL HEADER, with the
1644961713Sgirish  * fields enclosed by brackets "[]" replaced with your own identifying
1744961713Sgirish  * information: Portions Copyright [yyyy] [name of copyright owner]
1844961713Sgirish  *
1944961713Sgirish  * CDDL HEADER END
2044961713Sgirish  */
2144961713Sgirish /*
229d587972SSantwona Behera  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2344961713Sgirish  */
2444961713Sgirish 
25a3c5bd6dSspeer #include <sys/nxge/nxge_impl.h>
26a3c5bd6dSspeer #include <sys/nxge/nxge_mac.h>
27678453a8Sspeer #include <sys/nxge/nxge_hio.h>
2844961713Sgirish 
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  */
4044961713Sgirish static void nxge_get_niu_property(dev_info_t *, niu_type_t *);
4114ea4bb7Ssd static nxge_status_t nxge_get_mac_addr_properties(p_nxge_t);
4244961713Sgirish static nxge_status_t nxge_use_cfg_n2niu_properties(p_nxge_t);
4344961713Sgirish static void nxge_use_cfg_neptune_properties(p_nxge_t);
4444961713Sgirish static void nxge_use_cfg_dma_config(p_nxge_t);
4544961713Sgirish static void nxge_use_cfg_vlan_class_config(p_nxge_t);
4644961713Sgirish static void nxge_use_cfg_mac_class_config(p_nxge_t);
4744961713Sgirish static void nxge_use_cfg_class_config(p_nxge_t);
4844961713Sgirish static void nxge_use_cfg_link_cfg(p_nxge_t);
4944961713Sgirish static void nxge_set_hw_dma_config(p_nxge_t);
5044961713Sgirish static void nxge_set_hw_vlan_class_config(p_nxge_t);
5144961713Sgirish static void nxge_set_hw_mac_class_config(p_nxge_t);
5244961713Sgirish static void nxge_set_hw_class_config(p_nxge_t);
5344961713Sgirish static nxge_status_t nxge_use_default_dma_config_n2(p_nxge_t);
54a3c5bd6dSspeer static void nxge_ldgv_setup(p_nxge_ldg_t *, p_nxge_ldv_t *, uint8_t,
5544961713Sgirish 	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);
5844961713Sgirish 
59a3c5bd6dSspeer uint32_t nxge_use_hw_property = 1;
60a3c5bd6dSspeer uint32_t nxge_groups_per_port = 2;
6144961713Sgirish 
62a3c5bd6dSspeer extern uint32_t nxge_use_partition;
63a3c5bd6dSspeer extern uint32_t nxge_dma_obp_props_only;
6444961713Sgirish 
65*e3d11eeeSToomas Soome extern uint_t nxge_rx_intr(char *, char *);
66*e3d11eeeSToomas Soome extern uint_t nxge_tx_intr(char *, char *);
67*e3d11eeeSToomas Soome extern uint_t nxge_mif_intr(char *, char *);
68*e3d11eeeSToomas Soome extern uint_t nxge_mac_intr(char *, char *);
69*e3d11eeeSToomas Soome extern uint_t nxge_syserr_intr(char *, char *);
7044961713Sgirish extern void *nxge_list;
7144961713Sgirish 
7244961713Sgirish #define	NXGE_SHARED_REG_SW_SIM
7344961713Sgirish 
7444961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
7544961713Sgirish uint64_t global_dev_ctrl = 0;
7644961713Sgirish #endif
7744961713Sgirish 
7844961713Sgirish #define	MAX_SIBLINGS	NXGE_MAX_PORTS
7944961713Sgirish 
80a3c5bd6dSspeer extern uint32_t nxge_rbr_size;
81a3c5bd6dSspeer extern uint32_t nxge_rcr_size;
82a3c5bd6dSspeer extern uint32_t nxge_tx_ring_size;
83a3c5bd6dSspeer extern uint32_t nxge_rbr_spare_size;
8444961713Sgirish 
85a3c5bd6dSspeer extern npi_status_t npi_mac_altaddr_disable(npi_handle_t, uint8_t, uint8_t);
8644961713Sgirish 
8744961713Sgirish static uint8_t p2_tx_fair[2] = {12, 12};
8844961713Sgirish static uint8_t p2_tx_equal[2] = {12, 12};
8944961713Sgirish static uint8_t p4_tx_fair[4] = {6, 6, 6, 6};
9044961713Sgirish static uint8_t p4_tx_equal[4] = {6, 6, 6, 6};
9144961713Sgirish static uint8_t p2_rx_fair[2] = {8, 8};
9244961713Sgirish static uint8_t p2_rx_equal[2] = {8, 8};
9344961713Sgirish static uint8_t p4_rx_fair[4] = {4, 4, 4, 4};
9444961713Sgirish static uint8_t p4_rx_equal[4] = {4, 4, 4, 4};
9544961713Sgirish 
9644961713Sgirish static uint8_t p2_rdcgrp_fair[2] = {4, 4};
9744961713Sgirish static uint8_t p2_rdcgrp_equal[2] = {4, 4};
9844961713Sgirish static uint8_t p4_rdcgrp_fair[4] = {2, 2, 1, 1};
9944961713Sgirish static uint8_t p4_rdcgrp_equal[4] = {2, 2, 2, 2};
10044961713Sgirish static uint8_t p2_rdcgrp_cls[2] = {1, 1};
10144961713Sgirish static uint8_t p4_rdcgrp_cls[4] = {1, 1, 1, 1};
10244961713Sgirish 
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 
11544961713Sgirish typedef enum {
11644961713Sgirish 	DEFAULT = 0,
11744961713Sgirish 	EQUAL,
11844961713Sgirish 	FAIR,
11944961713Sgirish 	CUSTOM,
12044961713Sgirish 	CLASSIFY,
12144961713Sgirish 	L2_CLASSIFY,
12244961713Sgirish 	L3_DISTRIBUTE,
12344961713Sgirish 	L3_CLASSIFY,
12444961713Sgirish 	L3_TCAM,
12544961713Sgirish 	CONFIG_TOKEN_NONE
12644961713Sgirish } config_token_t;
12744961713Sgirish 
12844961713Sgirish static char *token_names[] = {
12944961713Sgirish 	"default",
13044961713Sgirish 	"equal",
13144961713Sgirish 	"fair",
13244961713Sgirish 	"custom",
13344961713Sgirish 	"classify",
13444961713Sgirish 	"l2_classify",
13544961713Sgirish 	"l3_distribute",
13644961713Sgirish 	"l3_classify",
13744961713Sgirish 	"l3_tcam",
13844961713Sgirish 	"none",
13944961713Sgirish };
14044961713Sgirish 
14144961713Sgirish void nxge_virint_regs_dump(p_nxge_t nxgep);
14244961713Sgirish 
14344961713Sgirish void
nxge_virint_regs_dump(p_nxge_t nxgep)14444961713Sgirish nxge_virint_regs_dump(p_nxge_t nxgep)
14544961713Sgirish {
146a3c5bd6dSspeer 	npi_handle_t handle;
14744961713Sgirish 
14844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "==> nxge_virint_regs_dump"));
14944961713Sgirish 	handle = NXGE_DEV_NPI_HANDLE(nxgep);
15044961713Sgirish 	(void) npi_vir_dump_pio_fzc_regs_one(handle);
15144961713Sgirish 	(void) npi_vir_dump_ldgnum(handle);
15244961713Sgirish 	(void) npi_vir_dump_ldsv(handle);
15344961713Sgirish 	(void) npi_vir_dump_imask0(handle);
15444961713Sgirish 	(void) npi_vir_dump_sid(handle);
15544961713Sgirish 	(void) npi_mac_dump_regs(handle, nxgep->function_num);
15644961713Sgirish 	(void) npi_ipp_dump_regs(handle, nxgep->function_num);
15744961713Sgirish 	(void) npi_fflp_dump_regs(handle);
15844961713Sgirish 	NXGE_DEBUG_MSG((nxgep, INT_CTL, "<== nxge_virint_regs_dump"));
15944961713Sgirish }
16044961713Sgirish 
16144961713Sgirish /*
16244961713Sgirish  * For now: we hard coded the DMA configurations.
16344961713Sgirish  *	    and assume for one partition only.
16444961713Sgirish  *
16544961713Sgirish  *       OBP. Then OBP will pass this partition's
16644961713Sgirish  *	 Neptune configurations to fcode to create
16744961713Sgirish  *	 properties for them.
16844961713Sgirish  *
16944961713Sgirish  *	Since Neptune(PCI-E) and NIU (Niagara-2) has
17044961713Sgirish  *	different bus interfaces, the driver needs
17144961713Sgirish  *	to know which bus it is connected to.
17244961713Sgirish  *  	Ravinder suggested: create a device property.
17344961713Sgirish  *	In partitioning environment, we cannot
17444961713Sgirish  *	use .conf file (need to check). If conf changes,
17544961713Sgirish  *	need to reboot the system.
17644961713Sgirish  *	The following function assumes that we will
17744961713Sgirish  *	retrieve its properties from a virtualized nexus driver.
17844961713Sgirish  */
17944961713Sgirish 
18044961713Sgirish nxge_status_t
nxge_cntlops(dev_info_t * dip,nxge_ctl_enum_t ctlop,void * arg,void * result)18144961713Sgirish nxge_cntlops(dev_info_t *dip, nxge_ctl_enum_t ctlop, void *arg, void *result)
18244961713Sgirish {
183a3c5bd6dSspeer 	nxge_status_t status = NXGE_OK;
18444961713Sgirish 	int instance;
185a3c5bd6dSspeer 	p_nxge_t nxgep;
186a3c5bd6dSspeer 
18744961713Sgirish #ifndef NXGE_SHARED_REG_SW_SIM
18844961713Sgirish 	npi_handle_t handle;
18944961713Sgirish 	uint16_t sr16, cr16;
19044961713Sgirish #endif
19144961713Sgirish 	instance = ddi_get_instance(dip);
192a3c5bd6dSspeer 	NXGE_DEBUG_MSG((NULL, VIR_CTL, "Instance %d ", instance));
193a3c5bd6dSspeer 
19444961713Sgirish 	if (nxge_list == NULL) {
19544961713Sgirish 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
19652ccf843Smisaki 		    "nxge_cntlops: nxge_list null"));
19744961713Sgirish 		return (NXGE_ERROR);
19844961713Sgirish 	}
19944961713Sgirish 	nxgep = (p_nxge_t)ddi_get_soft_state(nxge_list, instance);
20044961713Sgirish 	if (nxgep == NULL) {
20144961713Sgirish 		NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL,
20252ccf843Smisaki 		    "nxge_cntlops: nxgep null"));
20344961713Sgirish 		return (NXGE_ERROR);
20444961713Sgirish 	}
20544961713Sgirish #ifndef NXGE_SHARED_REG_SW_SIM
20644961713Sgirish 	handle = nxgep->npi_reg_handle;
20744961713Sgirish #endif
20844961713Sgirish 	switch (ctlop) {
20944961713Sgirish 	case NXGE_CTLOPS_NIUTYPE:
21044961713Sgirish 		nxge_get_niu_property(dip, (niu_type_t *)result);
21144961713Sgirish 		return (status);
212a3c5bd6dSspeer 
21344961713Sgirish 	case NXGE_CTLOPS_GET_SHARED_REG:
21444961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
21544961713Sgirish 		*(uint64_t *)result = global_dev_ctrl;
21644961713Sgirish 		return (0);
21744961713Sgirish #else
21844961713Sgirish 		status = npi_dev_func_sr_sr_get(handle, &sr16);
21944961713Sgirish 		*(uint16_t *)result = sr16;
22044961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
22152ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_GET_SHARED_REG"));
22244961713Sgirish 		return (0);
22344961713Sgirish #endif
22444961713Sgirish 
22544961713Sgirish 	case NXGE_CTLOPS_SET_SHARED_REG_LOCK:
22644961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
227a3c5bd6dSspeer 		global_dev_ctrl = *(uint64_t *)arg;
22844961713Sgirish 		return (0);
22944961713Sgirish #else
23044961713Sgirish 		status = NPI_FAILURE;
23144961713Sgirish 		while (status != NPI_SUCCESS)
23244961713Sgirish 			status = npi_dev_func_sr_lock_enter(handle);
23344961713Sgirish 
23444961713Sgirish 		sr16 = *(uint16_t *)arg;
23544961713Sgirish 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
23644961713Sgirish 		status = npi_dev_func_sr_lock_free(handle);
23744961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
23852ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
23944961713Sgirish 		return (0);
24044961713Sgirish #endif
24144961713Sgirish 
24244961713Sgirish 	case NXGE_CTLOPS_UPDATE_SHARED_REG:
24344961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
24444961713Sgirish 		global_dev_ctrl |= *(uint64_t *)arg;
24544961713Sgirish 		return (0);
24644961713Sgirish #else
24744961713Sgirish 		status = NPI_FAILURE;
24844961713Sgirish 		while (status != NPI_SUCCESS)
24944961713Sgirish 			status = npi_dev_func_sr_lock_enter(handle);
25044961713Sgirish 		status = npi_dev_func_sr_sr_get(handle, &sr16);
25144961713Sgirish 		sr16 |= *(uint16_t *)arg;
25244961713Sgirish 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
25344961713Sgirish 		status = npi_dev_func_sr_lock_free(handle);
25444961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
25552ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
25644961713Sgirish 		return (0);
25744961713Sgirish #endif
25844961713Sgirish 
25944961713Sgirish 	case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG_UL:
26044961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
26144961713Sgirish 		global_dev_ctrl |= *(uint64_t *)arg;
26244961713Sgirish 		return (0);
26344961713Sgirish #else
26444961713Sgirish 		status = npi_dev_func_sr_sr_get(handle, &sr16);
26544961713Sgirish 		cr16 = *(uint16_t *)arg;
26644961713Sgirish 		sr16 &= ~cr16;
26744961713Sgirish 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
26844961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
26952ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
27044961713Sgirish 		return (0);
27144961713Sgirish #endif
27244961713Sgirish 
27344961713Sgirish 	case NXGE_CTLOPS_CLEAR_BIT_SHARED_REG:
27444961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
27544961713Sgirish 		global_dev_ctrl |= *(uint64_t *)arg;
27644961713Sgirish 		return (0);
27744961713Sgirish #else
27844961713Sgirish 		status = NPI_FAILURE;
27944961713Sgirish 		while (status != NPI_SUCCESS)
28044961713Sgirish 			status = npi_dev_func_sr_lock_enter(handle);
28144961713Sgirish 		status = npi_dev_func_sr_sr_get(handle, &sr16);
28244961713Sgirish 		cr16 = *(uint16_t *)arg;
28344961713Sgirish 		sr16 &= ~cr16;
28444961713Sgirish 		status = npi_dev_func_sr_sr_set_only(handle, &sr16);
28544961713Sgirish 		status = npi_dev_func_sr_lock_free(handle);
28644961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
28752ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_SET_SHARED_REG"));
28844961713Sgirish 		return (0);
28944961713Sgirish #endif
29044961713Sgirish 
29144961713Sgirish 	case NXGE_CTLOPS_GET_LOCK_BLOCK:
29244961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
29344961713Sgirish 		global_dev_ctrl |= *(uint64_t *)arg;
29444961713Sgirish 		return (0);
29544961713Sgirish #else
29644961713Sgirish 		status = NPI_FAILURE;
29744961713Sgirish 		while (status != NPI_SUCCESS)
298a3c5bd6dSspeer 			status = npi_dev_func_sr_lock_enter(handle);
29944961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
30052ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_BLOCK"));
30144961713Sgirish 		return (0);
30244961713Sgirish #endif
30344961713Sgirish 	case NXGE_CTLOPS_GET_LOCK_TRY:
30444961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
30544961713Sgirish 		global_dev_ctrl |= *(uint64_t *)arg;
30644961713Sgirish 		return (0);
30744961713Sgirish #else
30844961713Sgirish 		status = npi_dev_func_sr_lock_enter(handle);
30944961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
31052ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_TRY"));
31144961713Sgirish 		if (status == NPI_SUCCESS)
31244961713Sgirish 			return (NXGE_OK);
31344961713Sgirish 		else
31444961713Sgirish 			return (NXGE_ERROR);
31544961713Sgirish #endif
31644961713Sgirish 	case NXGE_CTLOPS_FREE_LOCK:
31744961713Sgirish #ifdef NXGE_SHARED_REG_SW_SIM
31844961713Sgirish 		global_dev_ctrl |= *(uint64_t *)arg;
31944961713Sgirish 		return (0);
32044961713Sgirish #else
32144961713Sgirish 		status = npi_dev_func_sr_lock_free(handle);
32244961713Sgirish 		NXGE_DEBUG_MSG((NULL, VIR_CTL,
32352ccf843Smisaki 		    "nxge_cntlops: NXGE_CTLOPS_GET_LOCK_FREE"));
324a3c5bd6dSspeer 		if (status == NPI_SUCCESS)
32544961713Sgirish 			return (NXGE_OK);
32644961713Sgirish 		else
32744961713Sgirish 			return (NXGE_ERROR);
32844961713Sgirish #endif
32944961713Sgirish 
33044961713Sgirish 	default:
33144961713Sgirish 		status = NXGE_ERROR;
33244961713Sgirish 	}
33344961713Sgirish 
33444961713Sgirish 	return (status);
33544961713Sgirish }
33644961713Sgirish 
33744961713Sgirish void
nxge_common_lock_get(p_nxge_t nxgep)33844961713Sgirish nxge_common_lock_get(p_nxge_t nxgep)
33944961713Sgirish {
34044961713Sgirish 	uint32_t status = NPI_FAILURE;
34144961713Sgirish 	npi_handle_t handle;
34244961713Sgirish 
34344961713Sgirish #if	defined(NXGE_SHARE_REG_SW_SIM)
34444961713Sgirish 	return;
34544961713Sgirish #endif
34644961713Sgirish 	handle = nxgep->npi_reg_handle;
34744961713Sgirish 	while (status != NPI_SUCCESS)
34844961713Sgirish 		status = npi_dev_func_sr_lock_enter(handle);
34944961713Sgirish }
35044961713Sgirish 
35144961713Sgirish void
nxge_common_lock_free(p_nxge_t nxgep)35244961713Sgirish nxge_common_lock_free(p_nxge_t nxgep)
35344961713Sgirish {
35444961713Sgirish 	npi_handle_t handle;
355a3c5bd6dSspeer 
35644961713Sgirish #if	defined(NXGE_SHARE_REG_SW_SIM)
35744961713Sgirish 	return;
35844961713Sgirish #endif
35944961713Sgirish 	handle = nxgep->npi_reg_handle;
36044961713Sgirish 	(void) npi_dev_func_sr_lock_free(handle);
36144961713Sgirish }
36244961713Sgirish 
36356d930aeSspeer 
36444961713Sgirish static void
nxge_get_niu_property(dev_info_t * dip,niu_type_t * niu_type)36544961713Sgirish nxge_get_niu_property(dev_info_t *dip, niu_type_t *niu_type)
36644961713Sgirish {
367a3c5bd6dSspeer 	uchar_t *prop_val;
368a3c5bd6dSspeer 	uint_t prop_len;
36944961713Sgirish 
37059ac0c16Sdavemq 	*niu_type = NIU_TYPE_NONE;
37144961713Sgirish 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, 0,
37252ccf843Smisaki 	    "niu-type", (uchar_t **)&prop_val,
37352ccf843Smisaki 	    &prop_len) == DDI_PROP_SUCCESS) {
37444961713Sgirish 		if (strncmp("niu", (caddr_t)prop_val, (size_t)prop_len) == 0) {
37544961713Sgirish 			*niu_type = N2_NIU;
37644961713Sgirish 		}
37744961713Sgirish 		ddi_prop_free(prop_val);
37844961713Sgirish 	}
37944961713Sgirish }
38044961713Sgirish 
38144961713Sgirish static config_token_t
nxge_get_config_token(char * prop)38244961713Sgirish nxge_get_config_token(char *prop)
38344961713Sgirish {
38444961713Sgirish 	config_token_t token = DEFAULT;
385a3c5bd6dSspeer 
38644961713Sgirish 	while (token < CONFIG_TOKEN_NONE) {
38744961713Sgirish 		if (strncmp(prop, token_names[token], 4) == 0)
38844961713Sgirish 			break;
38944961713Sgirish 		token++;
39044961713Sgirish 	}
39144961713Sgirish 	return (token);
39244961713Sgirish }
39344961713Sgirish 
39444961713Sgirish /* per port */
39544961713Sgirish 
39644961713Sgirish static nxge_status_t
nxge_update_rxdma_grp_properties(p_nxge_t nxgep,config_token_t token,dev_info_t * s_dip[])39744961713Sgirish nxge_update_rxdma_grp_properties(p_nxge_t nxgep, config_token_t token,
398a3c5bd6dSspeer 	dev_info_t *s_dip[])
39944961713Sgirish {
40044961713Sgirish 	nxge_status_t status = NXGE_OK;
40144961713Sgirish 	int ddi_status;
40244961713Sgirish 	int num_ports = nxgep->nports;
40344961713Sgirish 	int port, bits, j;
40444961713Sgirish 	uint8_t start_grp = 0, num_grps = 0;
40544961713Sgirish 	p_nxge_param_t param_arr;
40644961713Sgirish 	uint32_t grp_bitmap[MAX_SIBLINGS];
40744961713Sgirish 	int custom_start_grp[MAX_SIBLINGS];
40844961713Sgirish 	int custom_num_grp[MAX_SIBLINGS];
40944961713Sgirish 	uint8_t bad_config = B_FALSE;
41044961713Sgirish 	char *start_prop, *num_prop, *cfg_prop;
41144961713Sgirish 
41244961713Sgirish 	start_grp = 0;
41344961713Sgirish 	param_arr = nxgep->param_arr;
41444961713Sgirish 	start_prop = param_arr[param_rdc_grps_start].fcode_name;
41544961713Sgirish 	num_prop = param_arr[param_rx_rdc_grps].fcode_name;
41644961713Sgirish 
41744961713Sgirish 	switch (token) {
418a3c5bd6dSspeer 	case FAIR:
419a3c5bd6dSspeer 		cfg_prop = "fair";
420a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
421a3c5bd6dSspeer 			custom_num_grp[port] =
42252ccf843Smisaki 			    (num_ports == 4) ?
42352ccf843Smisaki 			    p4_rdcgrp_fair[port] :
42452ccf843Smisaki 			    p2_rdcgrp_fair[port];
425a3c5bd6dSspeer 			custom_start_grp[port] = start_grp;
426a3c5bd6dSspeer 			start_grp += custom_num_grp[port];
427a3c5bd6dSspeer 		}
42844961713Sgirish 		break;
42944961713Sgirish 
430a3c5bd6dSspeer 	case EQUAL:
431a3c5bd6dSspeer 		cfg_prop = "equal";
432a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
433a3c5bd6dSspeer 			custom_num_grp[port] =
43452ccf843Smisaki 			    (num_ports == 4) ?
43552ccf843Smisaki 			    p4_rdcgrp_equal[port] :
43652ccf843Smisaki 			    p2_rdcgrp_equal[port];
437a3c5bd6dSspeer 			custom_start_grp[port] = start_grp;
438a3c5bd6dSspeer 			start_grp += custom_num_grp[port];
439a3c5bd6dSspeer 		}
440a3c5bd6dSspeer 		break;
44144961713Sgirish 
44244961713Sgirish 
443a3c5bd6dSspeer 	case CLASSIFY:
444a3c5bd6dSspeer 		cfg_prop = "classify";
445a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
446a3c5bd6dSspeer 			custom_num_grp[port] = (num_ports == 4) ?
44752ccf843Smisaki 			    p4_rdcgrp_cls[port] : p2_rdcgrp_cls[port];
448a3c5bd6dSspeer 			custom_start_grp[port] = start_grp;
449a3c5bd6dSspeer 			start_grp += custom_num_grp[port];
450a3c5bd6dSspeer 		}
451a3c5bd6dSspeer 		break;
45244961713Sgirish 
453a3c5bd6dSspeer 	case CUSTOM:
454a3c5bd6dSspeer 		cfg_prop = "custom";
455a3c5bd6dSspeer 		/* See if it is good config */
456a3c5bd6dSspeer 		num_grps = 0;
457a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
458a3c5bd6dSspeer 			custom_start_grp[port] =
45952ccf843Smisaki 			    ddi_prop_get_int(DDI_DEV_T_NONE, s_dip[port],
46052ccf843Smisaki 			    DDI_PROP_DONTPASS, start_prop, -1);
461a3c5bd6dSspeer 			if ((custom_start_grp[port] == -1) ||
46252ccf843Smisaki 			    (custom_start_grp[port] >=
46352ccf843Smisaki 			    NXGE_MAX_RDC_GRPS)) {
464a3c5bd6dSspeer 				bad_config = B_TRUE;
465a3c5bd6dSspeer 				break;
466a3c5bd6dSspeer 			}
467a3c5bd6dSspeer 			custom_num_grp[port] = ddi_prop_get_int(
46852ccf843Smisaki 			    DDI_DEV_T_NONE,
46952ccf843Smisaki 			    s_dip[port],
47052ccf843Smisaki 			    DDI_PROP_DONTPASS,
47152ccf843Smisaki 			    num_prop, -1);
472a3c5bd6dSspeer 
473a3c5bd6dSspeer 			if ((custom_num_grp[port] == -1) ||
47452ccf843Smisaki 			    (custom_num_grp[port] >
47552ccf843Smisaki 			    NXGE_MAX_RDC_GRPS) ||
47652ccf843Smisaki 			    ((custom_num_grp[port] +
47752ccf843Smisaki 			    custom_start_grp[port]) >=
47852ccf843Smisaki 			    NXGE_MAX_RDC_GRPS)) {
479a3c5bd6dSspeer 				bad_config = B_TRUE;
480a3c5bd6dSspeer 				break;
481a3c5bd6dSspeer 			}
482a3c5bd6dSspeer 			num_grps += custom_num_grp[port];
483a3c5bd6dSspeer 			if (num_grps > NXGE_MAX_RDC_GRPS) {
484a3c5bd6dSspeer 				bad_config = B_TRUE;
485a3c5bd6dSspeer 				break;
486a3c5bd6dSspeer 			}
487a3c5bd6dSspeer 			grp_bitmap[port] = 0;
488a3c5bd6dSspeer 			for (bits = 0;
48952ccf843Smisaki 			    bits < custom_num_grp[port];
49052ccf843Smisaki 			    bits++) {
491a3c5bd6dSspeer 				grp_bitmap[port] |=
49252ccf843Smisaki 				    (1 << (bits + custom_start_grp[port]));
49344961713Sgirish 			}
49444961713Sgirish 
495a3c5bd6dSspeer 		}
49644961713Sgirish 
497a3c5bd6dSspeer 		if (bad_config == B_FALSE) {
498a3c5bd6dSspeer 			/* check for overlap */
499a3c5bd6dSspeer 			for (port = 0; port < num_ports - 1; port++) {
500a3c5bd6dSspeer 				for (j = port + 1; j < num_ports; j++) {
501a3c5bd6dSspeer 					if (grp_bitmap[port] &
50252ccf843Smisaki 					    grp_bitmap[j]) {
503a3c5bd6dSspeer 						bad_config = B_TRUE;
504a3c5bd6dSspeer 						break;
505a3c5bd6dSspeer 					}
50644961713Sgirish 				}
507a3c5bd6dSspeer 				if (bad_config == B_TRUE)
508a3c5bd6dSspeer 					break;
50944961713Sgirish 			}
510a3c5bd6dSspeer 		}
511a3c5bd6dSspeer 		if (bad_config == B_TRUE) {
512a3c5bd6dSspeer 			/* use default config */
51344961713Sgirish 			for (port = 0; port < num_ports; port++) {
514a3c5bd6dSspeer 				custom_num_grp[port] =
51552ccf843Smisaki 				    (num_ports == 4) ?
51652ccf843Smisaki 				    p4_rx_fair[port] : p2_rx_fair[port];
51744961713Sgirish 				custom_start_grp[port] = start_grp;
51844961713Sgirish 				start_grp += custom_num_grp[port];
51944961713Sgirish 			}
520a3c5bd6dSspeer 		}
521a3c5bd6dSspeer 		break;
522a3c5bd6dSspeer 
523a3c5bd6dSspeer 	default:
524a3c5bd6dSspeer 		/* use default config */
525a3c5bd6dSspeer 		cfg_prop = "fair";
526a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
527a3c5bd6dSspeer 			custom_num_grp[port] = (num_ports == 4) ?
52852ccf843Smisaki 			    p4_rx_fair[port] : p2_rx_fair[port];
529a3c5bd6dSspeer 			custom_start_grp[port] = start_grp;
530a3c5bd6dSspeer 			start_grp += custom_num_grp[port];
531a3c5bd6dSspeer 		}
532a3c5bd6dSspeer 		break;
53344961713Sgirish 	}
53444961713Sgirish 
535a3c5bd6dSspeer 	/* Now Update the rx properties */
53644961713Sgirish 	for (port = 0; port < num_ports; port++) {
53744961713Sgirish 		ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port],
53852ccf843Smisaki 		    "rxdma-grp-cfg", cfg_prop);
53944961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
54044961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
54152ccf843Smisaki 			    " property %s not updating",
54252ccf843Smisaki 			    cfg_prop));
54344961713Sgirish 			status |= NXGE_DDI_FAILED;
54444961713Sgirish 		}
54544961713Sgirish 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
54652ccf843Smisaki 		    num_prop, custom_num_grp[port]);
54744961713Sgirish 
54844961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
54944961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55052ccf843Smisaki 			    " property %s not updating",
55152ccf843Smisaki 			    num_prop));
55244961713Sgirish 			status |= NXGE_DDI_FAILED;
55344961713Sgirish 		}
55444961713Sgirish 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
55552ccf843Smisaki 		    start_prop, custom_start_grp[port]);
55644961713Sgirish 
55744961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
55844961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
55952ccf843Smisaki 			    " property %s not updating",
56052ccf843Smisaki 			    start_prop));
56144961713Sgirish 			status |= NXGE_DDI_FAILED;
56244961713Sgirish 		}
56344961713Sgirish 	}
56444961713Sgirish 	if (status & NXGE_DDI_FAILED)
56544961713Sgirish 		status |= NXGE_ERROR;
56644961713Sgirish 
56744961713Sgirish 	return (status);
56844961713Sgirish }
56944961713Sgirish 
57044961713Sgirish static nxge_status_t
nxge_update_rxdma_properties(p_nxge_t nxgep,config_token_t token,dev_info_t * s_dip[])57144961713Sgirish nxge_update_rxdma_properties(p_nxge_t nxgep, config_token_t token,
572a3c5bd6dSspeer 	dev_info_t *s_dip[])
57344961713Sgirish {
57444961713Sgirish 	nxge_status_t status = NXGE_OK;
57544961713Sgirish 	int ddi_status;
57644961713Sgirish 	int num_ports = nxgep->nports;
57744961713Sgirish 	int port, bits, j;
57844961713Sgirish 	uint8_t start_rdc = 0, num_rdc = 0;
57944961713Sgirish 	p_nxge_param_t param_arr;
58044961713Sgirish 	uint32_t rdc_bitmap[MAX_SIBLINGS];
58144961713Sgirish 	int custom_start_rdc[MAX_SIBLINGS];
58244961713Sgirish 	int custom_num_rdc[MAX_SIBLINGS];
58344961713Sgirish 	uint8_t bad_config = B_FALSE;
58444961713Sgirish 	int *prop_val;
58544961713Sgirish 	uint_t prop_len;
58644961713Sgirish 	char *start_rdc_prop, *num_rdc_prop, *cfg_prop;
58744961713Sgirish 
58844961713Sgirish 	start_rdc = 0;
58944961713Sgirish 	param_arr = nxgep->param_arr;
59044961713Sgirish 	start_rdc_prop = param_arr[param_rxdma_channels_begin].fcode_name;
59144961713Sgirish 	num_rdc_prop = param_arr[param_rxdma_channels].fcode_name;
59244961713Sgirish 
59344961713Sgirish 	switch (token) {
594a3c5bd6dSspeer 	case FAIR:
595a3c5bd6dSspeer 		cfg_prop = "fair";
596a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
597a3c5bd6dSspeer 			custom_num_rdc[port] = (num_ports == 4) ?
59852ccf843Smisaki 			    p4_rx_fair[port] : p2_rx_fair[port];
599a3c5bd6dSspeer 			custom_start_rdc[port] = start_rdc;
600a3c5bd6dSspeer 			start_rdc += custom_num_rdc[port];
601a3c5bd6dSspeer 		}
602a3c5bd6dSspeer 		break;
60344961713Sgirish 
604a3c5bd6dSspeer 	case EQUAL:
605a3c5bd6dSspeer 		cfg_prop = "equal";
606a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
607a3c5bd6dSspeer 			custom_num_rdc[port] = (num_ports == 4) ?
60852ccf843Smisaki 			    p4_rx_equal[port] :
60952ccf843Smisaki 			    p2_rx_equal[port];
610a3c5bd6dSspeer 			custom_start_rdc[port] = start_rdc;
611a3c5bd6dSspeer 			start_rdc += custom_num_rdc[port];
612a3c5bd6dSspeer 		}
61344961713Sgirish 		break;
61444961713Sgirish 
615a3c5bd6dSspeer 	case CUSTOM:
616a3c5bd6dSspeer 		cfg_prop = "custom";
617a3c5bd6dSspeer 		/* See if it is good config */
618a3c5bd6dSspeer 		num_rdc = 0;
619a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
620a3c5bd6dSspeer 			ddi_status = ddi_prop_lookup_int_array(
62152ccf843Smisaki 			    DDI_DEV_T_ANY,
62252ccf843Smisaki 			    s_dip[port], 0,
62352ccf843Smisaki 			    start_rdc_prop,
62452ccf843Smisaki 			    &prop_val,
62552ccf843Smisaki 			    &prop_len);
626a3c5bd6dSspeer 			if (ddi_status == DDI_SUCCESS)
627a3c5bd6dSspeer 				custom_start_rdc[port] = *prop_val;
628a3c5bd6dSspeer 			else {
629a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
63052ccf843Smisaki 				    " %s custom start port %d"
63152ccf843Smisaki 				    " read failed ",
63252ccf843Smisaki 				    " rxdma-cfg", port));
633a3c5bd6dSspeer 				bad_config = B_TRUE;
634a3c5bd6dSspeer 				status |= NXGE_DDI_FAILED;
635a3c5bd6dSspeer 			}
636a3c5bd6dSspeer 			if ((custom_start_rdc[port] == -1) ||
63752ccf843Smisaki 			    (custom_start_rdc[port] >=
63852ccf843Smisaki 			    NXGE_MAX_RDCS)) {
639a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
64052ccf843Smisaki 				    " %s custom start %d"
64152ccf843Smisaki 				    " out of range %x ",
64252ccf843Smisaki 				    " rxdma-cfg",
64352ccf843Smisaki 				    port,
64452ccf843Smisaki 				    custom_start_rdc[port]));
645a3c5bd6dSspeer 				bad_config = B_TRUE;
646a3c5bd6dSspeer 				break;
647a3c5bd6dSspeer 			}
648a3c5bd6dSspeer 			ddi_status = ddi_prop_lookup_int_array(
64952ccf843Smisaki 			    DDI_DEV_T_ANY,
65052ccf843Smisaki 			    s_dip[port],
65152ccf843Smisaki 			    0,
65252ccf843Smisaki 			    num_rdc_prop,
65352ccf843Smisaki 			    &prop_val,
65452ccf843Smisaki 			    &prop_len);
655a3c5bd6dSspeer 
656a3c5bd6dSspeer 			if (ddi_status == DDI_SUCCESS)
657a3c5bd6dSspeer 				custom_num_rdc[port] = *prop_val;
658a3c5bd6dSspeer 			else {
659a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
66052ccf843Smisaki 				    " %s custom num port %d"
66152ccf843Smisaki 				    " read failed ",
66252ccf843Smisaki 				    "rxdma-cfg", port));
663a3c5bd6dSspeer 				bad_config = B_TRUE;
664a3c5bd6dSspeer 				status |= NXGE_DDI_FAILED;
66544961713Sgirish 			}
66644961713Sgirish 
667a3c5bd6dSspeer 			if ((custom_num_rdc[port] == -1) ||
66852ccf843Smisaki 			    (custom_num_rdc[port] >
66952ccf843Smisaki 			    NXGE_MAX_RDCS) ||
67052ccf843Smisaki 			    ((custom_num_rdc[port] +
67152ccf843Smisaki 			    custom_start_rdc[port]) >
67252ccf843Smisaki 			    NXGE_MAX_RDCS)) {
673a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
67452ccf843Smisaki 				    " %s custom num %d"
67552ccf843Smisaki 				    " out of range %x ",
67652ccf843Smisaki 				    " rxdma-cfg",
67752ccf843Smisaki 				    port, custom_num_rdc[port]));
678a3c5bd6dSspeer 				bad_config = B_TRUE;
679a3c5bd6dSspeer 				break;
68044961713Sgirish 			}
681a3c5bd6dSspeer 			num_rdc += custom_num_rdc[port];
682a3c5bd6dSspeer 			if (num_rdc > NXGE_MAX_RDCS) {
683a3c5bd6dSspeer 				bad_config = B_TRUE;
684a3c5bd6dSspeer 				break;
68544961713Sgirish 			}
686a3c5bd6dSspeer 			rdc_bitmap[port] = 0;
687a3c5bd6dSspeer 			for (bits = 0;
68852ccf843Smisaki 			    bits < custom_num_rdc[port]; bits++) {
689a3c5bd6dSspeer 				rdc_bitmap[port] |=
69052ccf843Smisaki 				    (1 << (bits + custom_start_rdc[port]));
691a3c5bd6dSspeer 			}
692a3c5bd6dSspeer 		}
69344961713Sgirish 
694a3c5bd6dSspeer 		if (bad_config == B_FALSE) {
695a3c5bd6dSspeer 			/* check for overlap */
696a3c5bd6dSspeer 			for (port = 0; port < num_ports - 1; port++) {
697a3c5bd6dSspeer 				for (j = port + 1; j < num_ports; j++) {
698a3c5bd6dSspeer 					if (rdc_bitmap[port] &
69952ccf843Smisaki 					    rdc_bitmap[j]) {
700a3c5bd6dSspeer 						NXGE_DEBUG_MSG((nxgep,
70152ccf843Smisaki 						    CFG_CTL,
70252ccf843Smisaki 						    " rxdma-cfg"
70352ccf843Smisaki 						    " property custom"
70452ccf843Smisaki 						    " bit overlap"
70552ccf843Smisaki 						    " %d %d ",
70652ccf843Smisaki 						    port, j));
707a3c5bd6dSspeer 						bad_config = B_TRUE;
708a3c5bd6dSspeer 						break;
709a3c5bd6dSspeer 					}
71044961713Sgirish 				}
711a3c5bd6dSspeer 				if (bad_config == B_TRUE)
712a3c5bd6dSspeer 					break;
71344961713Sgirish 			}
714a3c5bd6dSspeer 		}
715a3c5bd6dSspeer 		if (bad_config == B_TRUE) {
716a3c5bd6dSspeer 			/* use default config */
717a3c5bd6dSspeer 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
71852ccf843Smisaki 			    " rxdma-cfg property:"
71952ccf843Smisaki 			    " bad custom config:"
72052ccf843Smisaki 			    " use default"));
72144961713Sgirish 			for (port = 0; port < num_ports; port++) {
722a3c5bd6dSspeer 				custom_num_rdc[port] =
72352ccf843Smisaki 				    (num_ports == 4) ?
72452ccf843Smisaki 				    p4_rx_fair[port] :
72552ccf843Smisaki 				    p2_rx_fair[port];
72644961713Sgirish 				custom_start_rdc[port] = start_rdc;
72744961713Sgirish 				start_rdc += custom_num_rdc[port];
72844961713Sgirish 			}
729a3c5bd6dSspeer 		}
730a3c5bd6dSspeer 		break;
731a3c5bd6dSspeer 
732a3c5bd6dSspeer 	default:
733a3c5bd6dSspeer 		/* use default config */
734a3c5bd6dSspeer 		cfg_prop = "fair";
735a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
736a3c5bd6dSspeer 			custom_num_rdc[port] = (num_ports == 4) ?
73752ccf843Smisaki 			    p4_rx_fair[port] : p2_rx_fair[port];
738a3c5bd6dSspeer 			custom_start_rdc[port] = start_rdc;
739a3c5bd6dSspeer 			start_rdc += custom_num_rdc[port];
740a3c5bd6dSspeer 		}
741a3c5bd6dSspeer 		break;
74244961713Sgirish 	}
74344961713Sgirish 
744a3c5bd6dSspeer 	/* Now Update the rx properties */
74544961713Sgirish 	for (port = 0; port < num_ports; port++) {
74644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
74752ccf843Smisaki 		    " update property rxdma-cfg with %s ", cfg_prop));
74844961713Sgirish 		ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port],
74952ccf843Smisaki 		    "rxdma-cfg", cfg_prop);
75044961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
75144961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
75252ccf843Smisaki 			    " property rxdma-cfg is not updating to %s",
75352ccf843Smisaki 			    cfg_prop));
75444961713Sgirish 			status |= NXGE_DDI_FAILED;
75544961713Sgirish 		}
75644961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
75752ccf843Smisaki 		    num_rdc_prop, custom_num_rdc[port]));
75844961713Sgirish 
75944961713Sgirish 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
76052ccf843Smisaki 		    num_rdc_prop, custom_num_rdc[port]);
76144961713Sgirish 
76244961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
76344961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
76452ccf843Smisaki 			    " property %s not updating with %d",
76552ccf843Smisaki 			    num_rdc_prop, custom_num_rdc[port]));
76644961713Sgirish 			status |= NXGE_DDI_FAILED;
76744961713Sgirish 		}
76844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
76952ccf843Smisaki 		    start_rdc_prop, custom_start_rdc[port]));
77044961713Sgirish 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
77152ccf843Smisaki 		    start_rdc_prop, custom_start_rdc[port]);
77244961713Sgirish 
77344961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
77444961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
77552ccf843Smisaki 			    " property %s not updating with %d ",
77652ccf843Smisaki 			    start_rdc_prop, custom_start_rdc[port]));
77744961713Sgirish 			status |= NXGE_DDI_FAILED;
77844961713Sgirish 		}
77944961713Sgirish 	}
78044961713Sgirish 	if (status & NXGE_DDI_FAILED)
78144961713Sgirish 		status |= NXGE_ERROR;
78244961713Sgirish 	return (status);
78344961713Sgirish }
78444961713Sgirish 
78544961713Sgirish static nxge_status_t
nxge_update_txdma_properties(p_nxge_t nxgep,config_token_t token,dev_info_t * s_dip[])78644961713Sgirish nxge_update_txdma_properties(p_nxge_t nxgep, config_token_t token,
787a3c5bd6dSspeer 	dev_info_t *s_dip[])
78844961713Sgirish {
78944961713Sgirish 	nxge_status_t status = NXGE_OK;
79044961713Sgirish 	int ddi_status = DDI_SUCCESS;
79144961713Sgirish 	int num_ports = nxgep->nports;
79244961713Sgirish 	int port, bits, j;
793da14cebeSEric Cheng 	uint8_t  start_tdc, num_tdc = 0;
79444961713Sgirish 	p_nxge_param_t param_arr;
79544961713Sgirish 	uint32_t tdc_bitmap[MAX_SIBLINGS];
79644961713Sgirish 	int custom_start_tdc[MAX_SIBLINGS];
79744961713Sgirish 	int custom_num_tdc[MAX_SIBLINGS];
79844961713Sgirish 	uint8_t bad_config = B_FALSE;
79944961713Sgirish 	int *prop_val;
80044961713Sgirish 	uint_t prop_len;
80144961713Sgirish 	char *start_tdc_prop, *num_tdc_prop, *cfg_prop;
80244961713Sgirish 
80344961713Sgirish 	start_tdc = 0;
80444961713Sgirish 	param_arr = nxgep->param_arr;
80544961713Sgirish 	start_tdc_prop = param_arr[param_txdma_channels_begin].fcode_name;
80644961713Sgirish 	num_tdc_prop = param_arr[param_txdma_channels].fcode_name;
80744961713Sgirish 
80844961713Sgirish 	switch (token) {
809a3c5bd6dSspeer 	case FAIR:
810a3c5bd6dSspeer 		cfg_prop = "fair";
811a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
812a3c5bd6dSspeer 			custom_num_tdc[port] = (num_ports == 4) ?
81352ccf843Smisaki 			    p4_tx_fair[port] : p2_tx_fair[port];
814a3c5bd6dSspeer 			custom_start_tdc[port] = start_tdc;
815a3c5bd6dSspeer 			start_tdc += custom_num_tdc[port];
816a3c5bd6dSspeer 		}
817a3c5bd6dSspeer 		break;
81844961713Sgirish 
819a3c5bd6dSspeer 	case EQUAL:
820a3c5bd6dSspeer 		cfg_prop = "equal";
821a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
822a3c5bd6dSspeer 			custom_num_tdc[port] = (num_ports == 4) ?
82352ccf843Smisaki 			    p4_tx_equal[port] : p2_tx_equal[port];
824a3c5bd6dSspeer 			custom_start_tdc[port] = start_tdc;
825a3c5bd6dSspeer 			start_tdc += custom_num_tdc[port];
826a3c5bd6dSspeer 		}
82744961713Sgirish 		break;
82844961713Sgirish 
829a3c5bd6dSspeer 	case CUSTOM:
830a3c5bd6dSspeer 		cfg_prop = "custom";
831a3c5bd6dSspeer 		/* See if it is good config */
832a3c5bd6dSspeer 		num_tdc = 0;
833a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
834a3c5bd6dSspeer 			ddi_status = ddi_prop_lookup_int_array(
83552ccf843Smisaki 			    DDI_DEV_T_ANY, s_dip[port], 0, start_tdc_prop,
83652ccf843Smisaki 			    &prop_val, &prop_len);
837a3c5bd6dSspeer 			if (ddi_status == DDI_SUCCESS)
838a3c5bd6dSspeer 				custom_start_tdc[port] = *prop_val;
839a3c5bd6dSspeer 			else {
840a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
84152ccf843Smisaki 				    " %s custom start port %d"
84252ccf843Smisaki 				    " read failed ", " txdma-cfg", port));
843a3c5bd6dSspeer 				bad_config = B_TRUE;
844a3c5bd6dSspeer 				status |= NXGE_DDI_FAILED;
84544961713Sgirish 			}
84644961713Sgirish 
847a3c5bd6dSspeer 			if ((custom_start_tdc[port] == -1) ||
84852ccf843Smisaki 			    (custom_start_tdc[port] >=
84952ccf843Smisaki 			    NXGE_MAX_RDCS)) {
850a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
85152ccf843Smisaki 				    " %s custom start %d"
85252ccf843Smisaki 				    " out of range %x ", " txdma-cfg",
85352ccf843Smisaki 				    port, custom_start_tdc[port]));
854a3c5bd6dSspeer 				bad_config = B_TRUE;
855a3c5bd6dSspeer 				break;
856a3c5bd6dSspeer 			}
85744961713Sgirish 
858a3c5bd6dSspeer 			ddi_status = ddi_prop_lookup_int_array(
85952ccf843Smisaki 			    DDI_DEV_T_ANY, s_dip[port], 0, num_tdc_prop,
86052ccf843Smisaki 			    &prop_val, &prop_len);
861a3c5bd6dSspeer 			if (ddi_status == DDI_SUCCESS)
862a3c5bd6dSspeer 				custom_num_tdc[port] = *prop_val;
863a3c5bd6dSspeer 			else {
864a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
86552ccf843Smisaki 				    " %s custom num port %d"
86652ccf843Smisaki 				    " read failed ", " txdma-cfg", port));
867a3c5bd6dSspeer 				bad_config = B_TRUE;
868a3c5bd6dSspeer 				status |= NXGE_DDI_FAILED;
869a3c5bd6dSspeer 			}
87044961713Sgirish 
871a3c5bd6dSspeer 			if ((custom_num_tdc[port] == -1) ||
87252ccf843Smisaki 			    (custom_num_tdc[port] >
87352ccf843Smisaki 			    NXGE_MAX_TDCS) ||
87452ccf843Smisaki 			    ((custom_num_tdc[port] +
87552ccf843Smisaki 			    custom_start_tdc[port]) >
87652ccf843Smisaki 			    NXGE_MAX_TDCS)) {
877a3c5bd6dSspeer 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
87852ccf843Smisaki 				    " %s custom num %d"
87952ccf843Smisaki 				    " out of range %x ", " rxdma-cfg",
88052ccf843Smisaki 				    port, custom_num_tdc[port]));
881a3c5bd6dSspeer 				bad_config = B_TRUE;
882a3c5bd6dSspeer 				break;
88344961713Sgirish 			}
884a3c5bd6dSspeer 			num_tdc += custom_num_tdc[port];
885a3c5bd6dSspeer 			if (num_tdc > NXGE_MAX_TDCS) {
886a3c5bd6dSspeer 				bad_config = B_TRUE;
887a3c5bd6dSspeer 				break;
888a3c5bd6dSspeer 			}
889a3c5bd6dSspeer 			tdc_bitmap[port] = 0;
890a3c5bd6dSspeer 			for (bits = 0;
89152ccf843Smisaki 			    bits < custom_num_tdc[port]; bits++) {
892a3c5bd6dSspeer 				tdc_bitmap[port] |=
89352ccf843Smisaki 				    (1 <<
89452ccf843Smisaki 				    (bits + custom_start_tdc[port]));
89544961713Sgirish 			}
89644961713Sgirish 
897a3c5bd6dSspeer 		}
898a3c5bd6dSspeer 
899a3c5bd6dSspeer 		if (bad_config == B_FALSE) {
900a3c5bd6dSspeer 			/* check for overlap */
901a3c5bd6dSspeer 			for (port = 0; port < num_ports - 1; port++) {
902a3c5bd6dSspeer 				for (j = port + 1; j < num_ports; j++) {
903a3c5bd6dSspeer 					if (tdc_bitmap[port] &
90452ccf843Smisaki 					    tdc_bitmap[j]) {
905a3c5bd6dSspeer 						NXGE_DEBUG_MSG((nxgep, CFG_CTL,
90652ccf843Smisaki 						    " rxdma-cfg"
90752ccf843Smisaki 						    " property custom"
90852ccf843Smisaki 						    " bit overlap"
90952ccf843Smisaki 						    " %d %d ",
91052ccf843Smisaki 						    port, j));
911a3c5bd6dSspeer 						bad_config = B_TRUE;
912a3c5bd6dSspeer 						break;
913a3c5bd6dSspeer 					}
91444961713Sgirish 				}
915a3c5bd6dSspeer 				if (bad_config == B_TRUE)
916a3c5bd6dSspeer 					break;
91744961713Sgirish 			}
918a3c5bd6dSspeer 		}
919a3c5bd6dSspeer 		if (bad_config == B_TRUE) {
920a3c5bd6dSspeer 			/* use default config */
921a3c5bd6dSspeer 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
92252ccf843Smisaki 			    " txdma-cfg property:"
92352ccf843Smisaki 			    " bad custom config:" " use default"));
92444961713Sgirish 
92544961713Sgirish 			for (port = 0; port < num_ports; port++) {
92644961713Sgirish 				custom_num_tdc[port] = (num_ports == 4) ?
92752ccf843Smisaki 				    p4_tx_fair[port] : p2_tx_fair[port];
92844961713Sgirish 				custom_start_tdc[port] = start_tdc;
92944961713Sgirish 				start_tdc += custom_num_tdc[port];
93044961713Sgirish 			}
931a3c5bd6dSspeer 		}
932a3c5bd6dSspeer 		break;
933a3c5bd6dSspeer 
934a3c5bd6dSspeer 	default:
935a3c5bd6dSspeer 		/* use default config */
936a3c5bd6dSspeer 		cfg_prop = "fair";
937a3c5bd6dSspeer 		for (port = 0; port < num_ports; port++) {
938a3c5bd6dSspeer 			custom_num_tdc[port] = (num_ports == 4) ?
93952ccf843Smisaki 			    p4_tx_fair[port] : p2_tx_fair[port];
940a3c5bd6dSspeer 			custom_start_tdc[port] = start_tdc;
941a3c5bd6dSspeer 			start_tdc += custom_num_tdc[port];
942a3c5bd6dSspeer 		}
943a3c5bd6dSspeer 		break;
94444961713Sgirish 	}
94544961713Sgirish 
946a3c5bd6dSspeer 	/* Now Update the tx properties */
94744961713Sgirish 	for (port = 0; port < num_ports; port++) {
94844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
94952ccf843Smisaki 		    " update property txdma-cfg with %s ", cfg_prop));
95044961713Sgirish 		ddi_status = ddi_prop_update_string(DDI_DEV_T_NONE, s_dip[port],
95152ccf843Smisaki 		    "txdma-cfg", cfg_prop);
95244961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
95344961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
95452ccf843Smisaki 			    " property txdma-cfg is not updating to %s",
95552ccf843Smisaki 			    cfg_prop));
95644961713Sgirish 			status |= NXGE_DDI_FAILED;
95744961713Sgirish 		}
95844961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
95952ccf843Smisaki 		    num_tdc_prop, custom_num_tdc[port]));
96044961713Sgirish 
96144961713Sgirish 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
96252ccf843Smisaki 		    num_tdc_prop, custom_num_tdc[port]);
96344961713Sgirish 
96444961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
96544961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
96652ccf843Smisaki 			    " property %s not updating with %d",
96752ccf843Smisaki 			    num_tdc_prop,
96852ccf843Smisaki 			    custom_num_tdc[port]));
96944961713Sgirish 			status |= NXGE_DDI_FAILED;
97044961713Sgirish 		}
97144961713Sgirish 
97244961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL, " update property %s with %d ",
97352ccf843Smisaki 		    start_tdc_prop, custom_start_tdc[port]));
97444961713Sgirish 
975a3c5bd6dSspeer 		ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, s_dip[port],
97652ccf843Smisaki 		    start_tdc_prop, custom_start_tdc[port]);
97744961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS) {
97844961713Sgirish 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
97952ccf843Smisaki 			    " property %s not updating with %d ",
98052ccf843Smisaki 			    start_tdc_prop, custom_start_tdc[port]));
98144961713Sgirish 			status |= NXGE_DDI_FAILED;
98244961713Sgirish 		}
98344961713Sgirish 	}
98444961713Sgirish 	if (status & NXGE_DDI_FAILED)
98544961713Sgirish 		status |= NXGE_ERROR;
98644961713Sgirish 	return (status);
98744961713Sgirish }
98844961713Sgirish 
98944961713Sgirish static nxge_status_t
nxge_update_cfg_properties(p_nxge_t nxgep,uint32_t flags,config_token_t token,dev_info_t * s_dip[])99044961713Sgirish nxge_update_cfg_properties(p_nxge_t nxgep, uint32_t flags,
991a3c5bd6dSspeer 	config_token_t token, dev_info_t *s_dip[])
99244961713Sgirish {
99344961713Sgirish 	nxge_status_t status = NXGE_OK;
99444961713Sgirish 
99544961713Sgirish 	switch (flags) {
996a3c5bd6dSspeer 	case COMMON_TXDMA_CFG:
997a3c5bd6dSspeer 		if (nxge_dma_obp_props_only == 0)
99844961713Sgirish 			status = nxge_update_txdma_properties(nxgep,
99952ccf843Smisaki 			    token, s_dip);
1000a3c5bd6dSspeer 		break;
1001a3c5bd6dSspeer 	case COMMON_RXDMA_CFG:
1002a3c5bd6dSspeer 		if (nxge_dma_obp_props_only == 0)
100344961713Sgirish 			status = nxge_update_rxdma_properties(nxgep,
100452ccf843Smisaki 			    token, s_dip);
100544961713Sgirish 
1006a3c5bd6dSspeer 		break;
1007a3c5bd6dSspeer 	case COMMON_RXDMA_GRP_CFG:
1008a3c5bd6dSspeer 		status = nxge_update_rxdma_grp_properties(nxgep,
100952ccf843Smisaki 		    token, s_dip);
1010a3c5bd6dSspeer 		break;
1011a3c5bd6dSspeer 	default:
1012a3c5bd6dSspeer 		return (NXGE_ERROR);
101344961713Sgirish 	}
101444961713Sgirish 	return (status);
101544961713Sgirish }
101644961713Sgirish 
101744961713Sgirish /*
101844961713Sgirish  * verify consistence.
101944961713Sgirish  * (May require publishing the properties on all the ports.
102044961713Sgirish  *
102144961713Sgirish  * What if properties are published on function 0 device only?
102244961713Sgirish  *
102344961713Sgirish  *
102444961713Sgirish  * rxdma-cfg, txdma-cfg, rxdma-grp-cfg (required )
102544961713Sgirish  * What about class configs?
102644961713Sgirish  *
102744961713Sgirish  * If consistent, update the property on all the siblings.
102844961713Sgirish  * set  a flag on hardware shared register
102944961713Sgirish  * The rest of the siblings will check the flag
103044961713Sgirish  * if the flag is set, they will use the updated property
103144961713Sgirish  * without doing any validation.
103244961713Sgirish  */
103344961713Sgirish 
103444961713Sgirish nxge_status_t
nxge_cfg_verify_set_classify_prop(p_nxge_t nxgep,char * prop,uint64_t known_cfg,uint32_t override,dev_info_t * c_dip[])103544961713Sgirish nxge_cfg_verify_set_classify_prop(p_nxge_t nxgep, char *prop,
1036a3c5bd6dSspeer 	uint64_t known_cfg, uint32_t override, dev_info_t *c_dip[])
103744961713Sgirish {
103844961713Sgirish 	nxge_status_t status = NXGE_OK;
103944961713Sgirish 	int ddi_status = DDI_SUCCESS;
104044961713Sgirish 	int i = 0, found = 0, update_prop = B_TRUE;
1041a3c5bd6dSspeer 	int *cfg_val;
1042a3c5bd6dSspeer 	uint_t new_value, cfg_value[MAX_SIBLINGS];
1043a3c5bd6dSspeer 	uint_t prop_len;
104444961713Sgirish 	uint_t known_cfg_value;
104544961713Sgirish 
1046*e3d11eeeSToomas Soome 	new_value = 0;
104744961713Sgirish 	known_cfg_value = (uint_t)known_cfg;
104844961713Sgirish 
104944961713Sgirish 	if (override == B_TRUE) {
105044961713Sgirish 		new_value = known_cfg_value;
105144961713Sgirish 		for (i = 0; i < nxgep->nports; i++) {
105244961713Sgirish 			ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE,
105352ccf843Smisaki 			    c_dip[i], prop, new_value);
105444961713Sgirish #ifdef NXGE_DEBUG_ERROR
105544961713Sgirish 			if (ddi_status != DDI_PROP_SUCCESS)
105644961713Sgirish 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
105752ccf843Smisaki 				    " property %s failed update ", prop));
105844961713Sgirish #endif
105944961713Sgirish 		}
106044961713Sgirish 		if (ddi_status != DDI_PROP_SUCCESS)
106144961713Sgirish 			return (NXGE_ERROR | NXGE_DDI_FAILED);
106244961713Sgirish 	}
106344961713Sgirish 	for (i = 0; i < nxgep->nports; i++) {
106444961713Sgirish 		cfg_value[i] = known_cfg_value;
106544961713Sgirish 		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, c_dip[i], 0,
106652ccf843Smisaki 		    prop, &cfg_val,
106752ccf843Smisaki 		    &prop_len) == DDI_PROP_SUCCESS) {
106844961713Sgirish 			cfg_value[i] = *cfg_val;
106944961713Sgirish 			ddi_prop_free(cfg_val);
107044961713Sgirish 			found++;
107144961713Sgirish 		}
107244961713Sgirish 	}
107344961713Sgirish 
107444961713Sgirish 	if (found != i) {
107544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, CFG_CTL,
107652ccf843Smisaki 		    " property %s not specified on all ports", prop));
107744961713Sgirish 		if (found == 0) {
1078a3c5bd6dSspeer 			/* not specified: Use default */
107944961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
108052ccf843Smisaki 			    " property %s not specified on any port:"
108152ccf843Smisaki 			    " Using default", prop));
108244961713Sgirish 			new_value = known_cfg_value;
108344961713Sgirish 		} else {
1084a3c5bd6dSspeer 			/* specified on some */
108544961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
108652ccf843Smisaki 			    " property %s not specified"
108752ccf843Smisaki 			    " on some ports: Using default", prop));
108844961713Sgirish 			/* ? use p0 value instead ? */
108944961713Sgirish 			new_value = known_cfg_value;
109044961713Sgirish 		}
109144961713Sgirish 	} else {
109244961713Sgirish 		/* check type and consistence */
109344961713Sgirish 		/* found on all devices */
109444961713Sgirish 		for (i = 1; i < found; i++) {
1095a3c5bd6dSspeer 			if (cfg_value[i] != cfg_value[i - 1]) {
109644961713Sgirish 				NXGE_DEBUG_MSG((nxgep, CFG_CTL,
109752ccf843Smisaki 				    " property %s inconsistent:"
109852ccf843Smisaki 				    " Using default", prop));
109944961713Sgirish 				new_value = known_cfg_value;
110044961713Sgirish 				break;
1101a3c5bd6dSspeer 			}
1102a3c5bd6dSspeer 			/*
1103a3c5bd6dSspeer 			 * Found on all the ports and consistent. Nothing to
1104a3c5bd6dSspeer 			 * do.
1105a3c5bd6dSspeer 			 */
110644961713Sgirish 			update_prop = B_FALSE;
110744961713Sgirish 		}
110844961713Sgirish 	}
110944961713Sgirish 
111044961713Sgirish 	if (update_prop == B_TRUE) {
111144961713Sgirish 		for (i = 0; i < nxgep->nports; i++) {
111244961713Sgirish 			ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE,
111352ccf843Smisaki 			    c_dip[i], prop, new_value);
111444961713Sgirish #ifdef NXGE_DEBUG_ERROR
111544961713Sgirish 			if (ddi_status != DDI_SUCCESS)
111644961713Sgirish 				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
111752ccf843Smisaki 				    " property %s not updating with %d"
111852ccf843Smisaki 				    " Using default",
111952ccf843Smisaki 				    prop, new_value));
112044961713Sgirish #endif
112144961713Sgirish 			if (ddi_status != DDI_PROP_SUCCESS)
112244961713Sgirish 				status |= NXGE_DDI_FAILED;
112344961713Sgirish 		}
112444961713Sgirish 	}
112544961713Sgirish 	if (status & NXGE_DDI_FAILED)
112644961713Sgirish 		status |= NXGE_ERROR;
112744961713Sgirish 
112844961713Sgirish 	return (status);
112944961713Sgirish }
113044961713Sgirish 
113144961713Sgirish static uint64_t
nxge_class_get_known_cfg(p_nxge_t nxgep,int class_prop,int rx_quick_cfg)1132a3c5bd6dSspeer nxge_class_get_known_cfg(p_nxge_t nxgep, int class_prop, int rx_quick_cfg)
113344961713Sgirish {
1134a3c5bd6dSspeer 	int start_prop;
113544961713Sgirish 	uint64_t cfg_value;
113644961713Sgirish 	p_nxge_param_t param_arr;
113744961713Sgirish 
1138a3c5bd6dSspeer 	param_arr = nxgep->param_arr;
113944961713Sgirish 	cfg_value = param_arr[class_prop].value;
114044961713Sgirish 	start_prop = param_h1_init_value;
114144961713Sgirish 
114244961713Sgirish 	/* update the properties per quick config */
114344961713Sgirish 	switch (rx_quick_cfg) {
1144a3c5bd6dSspeer 	case CFG_L3_WEB:
1145a3c5bd6dSspeer 	case CFG_L3_DISTRIBUTE:
1146a3c5bd6dSspeer 		cfg_value = nxge_classify_get_cfg_value(nxgep,
114752ccf843Smisaki 		    rx_quick_cfg, class_prop - start_prop);
1148a3c5bd6dSspeer 		break;
1149a3c5bd6dSspeer 	default:
1150a3c5bd6dSspeer 		cfg_value = param_arr[class_prop].value;
1151a3c5bd6dSspeer 		break;
115244961713Sgirish 	}
115344961713Sgirish 	return (cfg_value);
115444961713Sgirish }
115544961713Sgirish 
115644961713Sgirish static nxge_status_t
nxge_cfg_verify_set_classify(p_nxge_t nxgep,dev_info_t * c_dip[])115744961713Sgirish nxge_cfg_verify_set_classify(p_nxge_t nxgep, dev_info_t *c_dip[])
115844961713Sgirish {
115944961713Sgirish 	nxge_status_t status = NXGE_OK;
1160a3c5bd6dSspeer 	int rx_quick_cfg, class_prop, start_prop, end_prop;
116144961713Sgirish 	char *prop_name;
116244961713Sgirish 	int override = B_TRUE;
116344961713Sgirish 	uint64_t cfg_value;
116444961713Sgirish 	p_nxge_param_t param_arr;
1165a3c5bd6dSspeer 
116644961713Sgirish 	param_arr = nxgep->param_arr;
116744961713Sgirish 	rx_quick_cfg = param_arr[param_rx_quick_cfg].value;
116844961713Sgirish 	start_prop = param_h1_init_value;
116944961713Sgirish 	end_prop = param_class_opt_ipv6_sctp;
117044961713Sgirish 
1171a3c5bd6dSspeer 	/* update the properties per quick config */
117244961713Sgirish 	if (rx_quick_cfg == CFG_NOT_SPECIFIED)
117344961713Sgirish 		override = B_FALSE;
1174a3c5bd6dSspeer 
1175a3c5bd6dSspeer 	/*
1176a3c5bd6dSspeer 	 * these parameter affect the classification outcome.
1177a3c5bd6dSspeer 	 * these parameters are used to configure the Flow key and
1178a3c5bd6dSspeer 	 * the TCAM key for each of the IP classes.
117958324dfcSspeer 	 * Included here are also the H1 and H2 initial values
1180a3c5bd6dSspeer 	 * which affect the distribution as well as final hash value
1181a3c5bd6dSspeer 	 * (hence the offset into RDC table and FCRAM bucket location)
1182a3c5bd6dSspeer 	 *
1183a3c5bd6dSspeer 	 */
1184a3c5bd6dSspeer 	for (class_prop = start_prop; class_prop <= end_prop; class_prop++) {
118544961713Sgirish 		prop_name = param_arr[class_prop].fcode_name;
118644961713Sgirish 		cfg_value = nxge_class_get_known_cfg(nxgep,
118752ccf843Smisaki 		    class_prop, rx_quick_cfg);
1188a3c5bd6dSspeer 		status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name,
118952ccf843Smisaki 		    cfg_value, override, c_dip);
119044961713Sgirish 	}
119144961713Sgirish 
1192a3c5bd6dSspeer 	/*
1193a3c5bd6dSspeer 	 * these properties do not affect the actual classification outcome.
1194a3c5bd6dSspeer 	 * used to enable/disable or tune the fflp hardware
1195a3c5bd6dSspeer 	 *
1196a3c5bd6dSspeer 	 * fcram_access_ratio, tcam_access_ratio, tcam_enable, llc_snap_enable
1197a3c5bd6dSspeer 	 *
1198a3c5bd6dSspeer 	 */
119944961713Sgirish 	override = B_FALSE;
120044961713Sgirish 	for (class_prop = param_fcram_access_ratio;
120152ccf843Smisaki 	    class_prop <= param_llc_snap_enable; class_prop++) {
120244961713Sgirish 		prop_name = param_arr[class_prop].fcode_name;
120344961713Sgirish 		cfg_value = param_arr[class_prop].value;
120444961713Sgirish 		status = nxge_cfg_verify_set_classify_prop(nxgep, prop_name,
120552ccf843Smisaki 		    cfg_value, override, c_dip);
120644961713Sgirish 	}
120744961713Sgirish 
1208a3c5bd6dSspeer 	return (status);
120944961713Sgirish }
121044961713Sgirish 
121144961713Sgirish nxge_status_t
nxge_cfg_verify_set(p_nxge_t nxgep,uint32_t flag)121244961713Sgirish nxge_cfg_verify_set(p_nxge_t nxgep, uint32_t flag)
121344961713Sgirish {
121444961713Sgirish 	nxge_status_t status = NXGE_OK;
121544961713Sgirish 	int i = 0, found = 0;
121644961713Sgirish 	int num_siblings;
1217a3c5bd6dSspeer 	dev_info_t *c_dip[MAX_SIBLINGS + 1];
121844961713Sgirish 	char *prop_val[MAX_SIBLINGS];
121944961713Sgirish 	config_token_t c_token[MAX_SIBLINGS];
122044961713Sgirish 	char *prop;
122144961713Sgirish 
1222a3c5bd6dSspeer 	if (nxge_dma_obp_props_only)
122344961713Sgirish 		return (NXGE_OK);
122444961713Sgirish 
122544961713Sgirish 	num_siblings = 0;
122644961713Sgirish 	c_dip[num_siblings] = ddi_get_child(nxgep->p_dip);
122744961713Sgirish 	while (c_dip[num_siblings]) {
122844961713Sgirish 		c_dip[num_siblings + 1] =
122952ccf843Smisaki 		    ddi_get_next_sibling(c_dip[num_siblings]);
123044961713Sgirish 		num_siblings++;
123144961713Sgirish 	}
123244961713Sgirish 
123344961713Sgirish 	switch (flag) {
1234a3c5bd6dSspeer 	case COMMON_TXDMA_CFG:
1235a3c5bd6dSspeer 		prop = "txdma-cfg";
1236a3c5bd6dSspeer 		break;
1237a3c5bd6dSspeer 	case COMMON_RXDMA_CFG:
1238a3c5bd6dSspeer 		prop = "rxdma-cfg";
1239a3c5bd6dSspeer 		break;
1240a3c5bd6dSspeer 	case COMMON_RXDMA_GRP_CFG:
1241a3c5bd6dSspeer 		prop = "rxdma-grp-cfg";
1242a3c5bd6dSspeer 		break;
1243a3c5bd6dSspeer 	case COMMON_CLASS_CFG:
1244a3c5bd6dSspeer 		status = nxge_cfg_verify_set_classify(nxgep, c_dip);
1245a3c5bd6dSspeer 		return (status);
1246a3c5bd6dSspeer 	default:
1247a3c5bd6dSspeer 		return (NXGE_ERROR);
124844961713Sgirish 	}
124944961713Sgirish 
125044961713Sgirish 	i = 0;
125144961713Sgirish 	while (i < num_siblings) {
1252a3c5bd6dSspeer 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, c_dip[i], 0, prop,
125352ccf843Smisaki 		    (char **)&prop_val[i]) == DDI_PROP_SUCCESS) {
125444961713Sgirish 			c_token[i] = nxge_get_config_token(prop_val[i]);
125544961713Sgirish 			ddi_prop_free(prop_val[i]);
125644961713Sgirish 			found++;
125744961713Sgirish 		} else
125844961713Sgirish 			c_token[i] = CONFIG_TOKEN_NONE;
125944961713Sgirish 		i++;
126044961713Sgirish 	}
126144961713Sgirish 
126244961713Sgirish 	if (found != i) {
126344961713Sgirish 		if (found == 0) {
1264a3c5bd6dSspeer 			/* not specified: Use default */
126544961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
126652ccf843Smisaki 			    " property %s not specified on any port:"
126752ccf843Smisaki 			    " Using default", prop));
126844961713Sgirish 
126944961713Sgirish 			status = nxge_update_cfg_properties(nxgep,
127052ccf843Smisaki 			    flag, FAIR, c_dip);
127144961713Sgirish 			return (status);
127244961713Sgirish 		} else {
127344961713Sgirish 			/*
1274a3c5bd6dSspeer 			 * if  the convention is to use function 0 device then
1275a3c5bd6dSspeer 			 * populate the other devices with this configuration.
127644961713Sgirish 			 *
127744961713Sgirish 			 * The other alternative is to use the default config.
127844961713Sgirish 			 */
1279a3c5bd6dSspeer 			/* not specified: Use default */
128044961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
128152ccf843Smisaki 			    " property %s not specified on some ports:"
128252ccf843Smisaki 			    " Using default", prop));
128344961713Sgirish 			status = nxge_update_cfg_properties(nxgep,
128452ccf843Smisaki 			    flag, FAIR, c_dip);
128544961713Sgirish 			return (status);
128644961713Sgirish 		}
128744961713Sgirish 	}
128844961713Sgirish 
1289a3c5bd6dSspeer 	/* check type and consistence */
1290a3c5bd6dSspeer 	/* found on all devices */
1291a3c5bd6dSspeer 	for (i = 1; i < found; i++) {
1292a3c5bd6dSspeer 		if (c_token[i] != c_token[i - 1]) {
129344961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
129452ccf843Smisaki 			    " property %s inconsistent:"
129552ccf843Smisaki 			    " Using default", prop));
129644961713Sgirish 			status = nxge_update_cfg_properties(nxgep,
129752ccf843Smisaki 			    flag, FAIR, c_dip);
129844961713Sgirish 			return (status);
129944961713Sgirish 		}
130044961713Sgirish 	}
130144961713Sgirish 
1302a3c5bd6dSspeer 	/*
1303a3c5bd6dSspeer 	 * Found on all the ports check if it is custom configuration. if
1304a3c5bd6dSspeer 	 * custom, then verify consistence
1305a3c5bd6dSspeer 	 *
1306a3c5bd6dSspeer 	 * finally create soft properties
1307a3c5bd6dSspeer 	 */
1308a3c5bd6dSspeer 	status = nxge_update_cfg_properties(nxgep, flag, c_token[0], c_dip);
130944961713Sgirish 	return (status);
131044961713Sgirish }
131144961713Sgirish 
131244961713Sgirish nxge_status_t
nxge_cfg_verify_set_quick_config(p_nxge_t nxgep)131344961713Sgirish nxge_cfg_verify_set_quick_config(p_nxge_t nxgep)
131444961713Sgirish {
131544961713Sgirish 	nxge_status_t status = NXGE_OK;
131644961713Sgirish 	int ddi_status = DDI_SUCCESS;
131744961713Sgirish 	char *prop_val;
131844961713Sgirish 	char *rx_prop;
131944961713Sgirish 	char *prop;
132044961713Sgirish 	uint32_t cfg_value = CFG_NOT_SPECIFIED;
132144961713Sgirish 	p_nxge_param_t param_arr;
132244961713Sgirish 
1323a3c5bd6dSspeer 	param_arr = nxgep->param_arr;
132444961713Sgirish 	rx_prop = param_arr[param_rx_quick_cfg].fcode_name;
132544961713Sgirish 
132644961713Sgirish 	prop = "rx-quick-cfg";
132744961713Sgirish 
1328a3c5bd6dSspeer 	/*
1329a3c5bd6dSspeer 	 * good value are
1330a3c5bd6dSspeer 	 *
1331a3c5bd6dSspeer 	 * "web-server" "generic-server" "l3-classify" "flow-classify"
1332a3c5bd6dSspeer 	 */
133344961713Sgirish 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, nxgep->dip, 0,
133452ccf843Smisaki 	    prop, (char **)&prop_val) != DDI_PROP_SUCCESS) {
133544961713Sgirish 		NXGE_DEBUG_MSG((nxgep, VPD_CTL,
133652ccf843Smisaki 		    " property %s not specified: using default ", prop));
133744961713Sgirish 		cfg_value = CFG_NOT_SPECIFIED;
133844961713Sgirish 	} else {
133944961713Sgirish 		cfg_value = CFG_L3_DISTRIBUTE;
134044961713Sgirish 		if (strncmp("web-server", (caddr_t)prop_val, 8) == 0) {
134144961713Sgirish 			cfg_value = CFG_L3_WEB;
134244961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
134352ccf843Smisaki 			    " %s: web server ", prop));
134444961713Sgirish 		}
134544961713Sgirish 		if (strncmp("generic-server", (caddr_t)prop_val, 8) == 0) {
134644961713Sgirish 			cfg_value = CFG_L3_DISTRIBUTE;
134744961713Sgirish 			NXGE_DEBUG_MSG((nxgep, CFG_CTL,
134852ccf843Smisaki 			    " %s: distribute ", prop));
134944961713Sgirish 		}
135044961713Sgirish 		/* more */
135144961713Sgirish 		ddi_prop_free(prop_val);
135244961713Sgirish 	}
135344961713Sgirish 
135444961713Sgirish 	ddi_status = ddi_prop_update_int(DDI_DEV_T_NONE, nxgep->dip,
135552ccf843Smisaki 	    rx_prop, cfg_value);
135644961713Sgirish 	if (ddi_status != DDI_PROP_SUCCESS)
135744961713Sgirish 		status |= NXGE_DDI_FAILED;
135844961713Sgirish 
1359a3c5bd6dSspeer 	/* now handle specified cases: */
136044961713Sgirish 	if (status & NXGE_DDI_FAILED)
136144961713Sgirish 		status |= NXGE_ERROR;
136244961713Sgirish 	return (status);
136344961713Sgirish }
136444961713Sgirish 
136500161856Syc /*
136600161856Syc  * Device properties adv-autoneg-cap etc are defined by FWARC
136700161856Syc  * http://sac.sfbay/FWARC/2002/345/20020610_asif.haswarey
136800161856Syc  */
136944961713Sgirish static void
nxge_use_cfg_link_cfg(p_nxge_t nxgep)137044961713Sgirish nxge_use_cfg_link_cfg(p_nxge_t nxgep)
137144961713Sgirish {
137244961713Sgirish 	int *prop_val;
137344961713Sgirish 	uint_t prop_len;
137444961713Sgirish 	dev_info_t *dip;
137544961713Sgirish 	int speed;
137644961713Sgirish 	int duplex;
137744961713Sgirish 	int adv_autoneg_cap;
137844961713Sgirish 	int adv_10gfdx_cap;
137944961713Sgirish 	int adv_10ghdx_cap;
138044961713Sgirish 	int adv_1000fdx_cap;
138144961713Sgirish 	int adv_1000hdx_cap;
138244961713Sgirish 	int adv_100fdx_cap;
138344961713Sgirish 	int adv_100hdx_cap;
138444961713Sgirish 	int adv_10fdx_cap;
138544961713Sgirish 	int adv_10hdx_cap;
138644961713Sgirish 	int status = DDI_SUCCESS;
138744961713Sgirish 
138844961713Sgirish 	dip = nxgep->dip;
1389a3c5bd6dSspeer 
1390a3c5bd6dSspeer 	/*
1391a3c5bd6dSspeer 	 * first find out the card type and the supported link speeds and
1392a3c5bd6dSspeer 	 * features
1393a3c5bd6dSspeer 	 */
1394a3c5bd6dSspeer 	/* add code for card type */
139544961713Sgirish 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-autoneg-cap",
139652ccf843Smisaki 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
139744961713Sgirish 		ddi_prop_free(prop_val);
1398a3c5bd6dSspeer 		return;
139944961713Sgirish 	}
1400a3c5bd6dSspeer 
140144961713Sgirish 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-10gfdx-cap",
140252ccf843Smisaki 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
140344961713Sgirish 		ddi_prop_free(prop_val);
1404a3c5bd6dSspeer 		return;
140544961713Sgirish 	}
1406a3c5bd6dSspeer 
140744961713Sgirish 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000hdx-cap",
140852ccf843Smisaki 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
140944961713Sgirish 		ddi_prop_free(prop_val);
1410a3c5bd6dSspeer 		return;
141144961713Sgirish 	}
1412a3c5bd6dSspeer 
141344961713Sgirish 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-1000fdx-cap",
141452ccf843Smisaki 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
141544961713Sgirish 		ddi_prop_free(prop_val);
1416a3c5bd6dSspeer 		return;
141744961713Sgirish 	}
1418a3c5bd6dSspeer 
141944961713Sgirish 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0, "adv-100fdx-cap",
142052ccf843Smisaki 	    &prop_val, &prop_len) == DDI_PROP_SUCCESS) {
142144961713Sgirish 		ddi_prop_free(prop_val);
1422a3c5bd6dSspeer 		return;
142344961713Sgirish 	}
1424a3c5bd6dSspeer 
142544961713Sgirish