13dec9fcqs/*
23dec9fcqs * CDDL HEADER START
33dec9fcqs *
43dec9fcqs * The contents of this file are subject to the terms of the
53dec9fcqs * Common Development and Distribution License (the "License").
63dec9fcqs * You may not use this file except in compliance with the License.
73dec9fcqs *
83dec9fcqs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93dec9fcqs * or http://www.opensolaris.org/os/licensing.
103dec9fcqs * See the License for the specific language governing permissions
113dec9fcqs * and limitations under the License.
123dec9fcqs *
133dec9fcqs * When distributing Covered Code, include this CDDL HEADER in each
143dec9fcqs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153dec9fcqs * If applicable, add the following below this CDDL HEADER, with the
163dec9fcqs * fields enclosed by brackets "[]" replaced with your own identifying
173dec9fcqs * information: Portions Copyright [yyyy] [name of copyright owner]
183dec9fcqs *
193dec9fcqs * CDDL HEADER END
203dec9fcqs */
213dec9fcqs/*
223dec9fcqs * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233dec9fcqs * Use is subject to license terms.
243dec9fcqs */
253dec9fcqs
263dec9fcqs#include <hxge_impl.h>
273dec9fcqs#include <inet/common.h>
283dec9fcqs#include <inet/mi.h>
293dec9fcqs#include <inet/nd.h>
303dec9fcqs
313dec9fcqsextern uint64_t hpi_debug_level;
323dec9fcqs
333dec9fcqs#define	HXGE_PARAM_MAC_RW \
343dec9fcqs	HXGE_PARAM_RW | HXGE_PARAM_MAC | \
353dec9fcqs	HXGE_PARAM_NDD_WR_OK | HXGE_PARAM_READ_PROP
363dec9fcqs
373dec9fcqs#define	HXGE_PARAM_RXDMA_RW	HXGE_PARAM_RWP | HXGE_PARAM_RXDMA | \
383dec9fcqs	HXGE_PARAM_NDD_WR_OK | HXGE_PARAM_READ_PROP
393dec9fcqs
403dec9fcqs#define	HXGE_PARAM_L2CLASS_CFG	\
413dec9fcqs	HXGE_PARAM_RW | HXGE_PARAM_PROP_ARR32 | \
423dec9fcqs	HXGE_PARAM_READ_PROP | HXGE_PARAM_NDD_WR_OK
433dec9fcqs
443dec9fcqs#define	HXGE_PARAM_CLASS_RWS \
453dec9fcqs	HXGE_PARAM_RWS | HXGE_PARAM_READ_PROP
463dec9fcqs
473dec9fcqs#define	HXGE_PARAM_ARRAY_INIT_SIZE	0x20ULL
483dec9fcqs
493dec9fcqs#define	BASE_ANY	0
503dec9fcqs#define	BASE_BINARY	2
513dec9fcqs#define	BASE_HEX	16
523dec9fcqs#define	BASE_DECIMAL	10
533dec9fcqs#define	ALL_FF_64	0xFFFFFFFFFFFFFFFFULL
543dec9fcqs#define	ALL_FF_32	0xFFFFFFFFUL
553dec9fcqs
563dec9fcqs#define	HXGE_NDD_INFODUMP_BUFF_SIZE	2048	/* is 2k enough? */
573dec9fcqs#define	HXGE_NDD_INFODUMP_BUFF_8K	8192
583dec9fcqs#define	HXGE_NDD_INFODUMP_BUFF_16K	0x2000
593dec9fcqs#define	HXGE_NDD_INFODUMP_BUFF_64K	0x8000
603dec9fcqs
613dec9fcqs#define	PARAM_OUTOF_RANGE(vptr, eptr, rval, pa)	\
623dec9fcqs	((vptr == eptr) || (rval < pa->minimum) || (rval > pa->maximum))
633dec9fcqs
643dec9fcqs#define	ADVANCE_PRINT_BUFFER(pmp, plen, rlen) { \
653dec9fcqs	((mblk_t *)pmp)->b_wptr += plen; \
663dec9fcqs	rlen -= plen; \
673dec9fcqs}
683dec9fcqs
69a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint hxge_param_rx_intr_pkts(p_hxge_t hxgep, queue_t *,
703dec9fcqs	mblk_t *, char *, caddr_t);
71a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint hxge_param_rx_intr_time(p_hxge_t hxgep, queue_t *,
723dec9fcqs	mblk_t *, char *, caddr_t);
733dec9fcqsstatic int hxge_param_set_mac(p_hxge_t, queue_t *,
743dec9fcqs	mblk_t *, char *, caddr_t);
753dec9fcqsstatic int hxge_param_set_ether_usr(p_hxge_t hxgep, queue_t *, mblk_t *,
763dec9fcqs	char *, caddr_t);
77a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint hxge_param_set_ip_opt(p_hxge_t hxgep,
783dec9fcqs	queue_t *, mblk_t *, char *, caddr_t);
793dec9fcqsstatic int hxge_param_pfc_hash_init(p_hxge_t hxgep,
803dec9fcqs	queue_t *, mblk_t *, char *, caddr_t);
813dec9fcqsstatic int hxge_param_tcam_enable(p_hxge_t hxgep, queue_t *,
823dec9fcqs	mblk_t *, char *, caddr_t);
833dec9fcqsstatic int hxge_param_get_rxdma_info(p_hxge_t hxgep, queue_t *q,
843dec9fcqs	p_mblk_t mp, caddr_t cp);
853dec9fcqsstatic int hxge_param_set_vlan_ids(p_hxge_t hxgep, queue_t *q,
863dec9fcqs	mblk_t *mp, char *value, caddr_t cp);
873dec9fcqsstatic int hxge_param_get_vlan_ids(p_hxge_t hxgep, queue_t *q,
883dec9fcqs	p_mblk_t mp, caddr_t cp);
89a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint hxge_param_get_ip_opt(p_hxge_t hxgep,
903dec9fcqs	queue_t *, mblk_t *, caddr_t);
913dec9fcqsstatic int hxge_param_get_mac(p_hxge_t hxgep, queue_t *q, p_mblk_t mp,
923dec9fcqs	caddr_t cp);
933dec9fcqsstatic int hxge_param_get_debug_flag(p_hxge_t hxgep, queue_t *q,
943dec9fcqs	p_mblk_t mp, caddr_t cp);
953dec9fcqsstatic int hxge_param_set_hxge_debug_flag(p_hxge_t hxgep,
963dec9fcqs	queue_t *, mblk_t *, char *, caddr_t);
973dec9fcqsstatic int hxge_param_set_hpi_debug_flag(p_hxge_t hxgep,
983dec9fcqs	queue_t *, mblk_t *, char *, caddr_t);
993dec9fcqsstatic int hxge_param_dump_ptrs(p_hxge_t hxgep, queue_t *q,
1003dec9fcqs	p_mblk_t mp, caddr_t cp);
1013dec9fcqs
1023dec9fcqs/*
1033dec9fcqs * Global array of Hydra changable parameters.
1043dec9fcqs * This array is initialized to correspond to the default
1053dec9fcqs * Hydra configuration. This array would be copied
1063dec9fcqs * into the parameter structure and modifed per
1073dec9fcqs * fcode and hxge.conf configuration. Later, the parameters are
1083dec9fcqs * exported to ndd to display and run-time configuration (at least
1093dec9fcqs * some of them).
1103dec9fcqs */
1113dec9fcqs
1123dec9fcqsstatic hxge_param_t hxge_param_arr[] = {
1133dec9fcqs	/* min	max	value	old	hw-name 	conf-name	*/
1143dec9fcqs	{hxge_param_get_generic, NULL, HXGE_PARAM_READ,
1153dec9fcqs		0, 999, 1000, 0, "instance", "instance"},
1163dec9fcqs
1173dec9fcqs	/* MTU cannot be propagated to the stack from here, so don't show it */
1183dec9fcqs	{hxge_param_get_mac, hxge_param_set_mac,
1193dec9fcqs		HXGE_PARAM_MAC_RW | HXGE_PARAM_DONT_SHOW,
1203dec9fcqs		0, 1, 0, 0, "accept-jumbo", "accept_jumbo"},
1213dec9fcqs
1223dec9fcqs	{hxge_param_get_rxdma_info, NULL,
1233dec9fcqs		HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW,
1243dec9fcqs		HXGE_RBR_RBB_MIN, HXGE_RBR_RBB_MAX, HXGE_RBR_RBB_DEFAULT, 0,
1253dec9fcqs		"rx-rbr-size", "rx_rbr_size"},
1263dec9fcqs
1273dec9fcqs	{hxge_param_get_rxdma_info, NULL,
1283dec9fcqs		HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW,
1293dec9fcqs		HXGE_RCR_MIN, HXGE_RCR_MAX, HXGE_RCR_DEFAULT, 0,
1303dec9fcqs		"rx-rcr-size", "rx_rcr_size"},
1313dec9fcqs
1323dec9fcqs	{hxge_param_get_generic, hxge_param_rx_intr_time,
1333dec9fcqs		HXGE_PARAM_RXDMA_RW,
1343dec9fcqs		HXGE_RDC_RCR_TIMEOUT_MIN, HXGE_RDC_RCR_TIMEOUT_MAX,
1353dec9fcqs		RXDMA_RCR_TO_DEFAULT, 0, "rxdma-intr-time", "rxdma_intr_time"},
1363dec9fcqs
1373dec9fcqs	{hxge_param_get_generic, hxge_param_rx_intr_pkts,
1383dec9fcqs		HXGE_PARAM_RXDMA_RW,
1393dec9fcqs		HXGE_RDC_RCR_THRESHOLD_MIN, HXGE_RDC_RCR_THRESHOLD_MAX,
1403dec9fcqs		RXDMA_RCR_PTHRES_DEFAULT, 0,
1413dec9fcqs		"rxdma-intr-pkts", "rxdma_intr_pkts"},
1423dec9fcqs
1433dec9fcqs	/* Hardware VLAN is not used currently, so don't show it */
1443dec9fcqs	{hxge_param_get_vlan_ids, hxge_param_set_vlan_ids,
1453dec9fcqs		HXGE_PARAM_L2CLASS_CFG | HXGE_PARAM_DONT_SHOW,
1463dec9fcqs		VLAN_ID_MIN, VLAN_ID_MAX, 0, 0, "vlan-ids", "vlan_ids"},
1473dec9fcqs
1483dec9fcqs	/* Hardware VLAN is not used currently, so don't show it */
1493dec9fcqs	{hxge_param_get_generic, hxge_param_set_generic,
1503dec9fcqs		HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW,
1513dec9fcqs		VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_IMPLICIT, VLAN_ID_IMPLICIT,
1523dec9fcqs		"implicit-vlan-id", "implicit_vlan_id"},
1533dec9fcqs
1543dec9fcqs	{hxge_param_get_generic, hxge_param_tcam_enable,
1553dec9fcqs		HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW,
1563dec9fcqs		0, 0x1, 0x0, 0, "tcam-enable", "tcam_enable"},
1573dec9fcqs
1583dec9fcqs	{hxge_param_get_generic, hxge_param_pfc_hash_init,
1593dec9fcqs		HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW,
1603dec9fcqs		0, ALL_FF_32, ALL_FF_32, 0,
1613dec9fcqs		"hash-init-value", "hash_init_value"},
1623dec9fcqs
1633dec9fcqs	{hxge_param_get_generic, hxge_param_set_ether_usr,
1643dec9fcqs		HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW,
1653dec9fcqs		0, ALL_FF_32, 0x0, 0,
1663dec9fcqs		"class-cfg-ether-usr1", "class_cfg_ether_usr1"},
1673dec9fcqs
1683dec9fcqs	{hxge_param_get_generic, hxge_param_set_ether_usr,
1693dec9fcqs		HXGE_PARAM_CLASS_RWS | HXGE_PARAM_DONT_SHOW,
1703dec9fcqs		0, ALL_FF_32, 0x0, 0,
1713dec9fcqs		"class-cfg-ether-usr2", "class_cfg_ether_usr2"},
1723dec9fcqs
1733dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1743dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1753dec9fcqs		"class-opt-ipv4-tcp", "class_opt_ipv4_tcp"},
1763dec9fcqs
1773dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1783dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1793dec9fcqs		"class-opt-ipv4-udp", "class_opt_ipv4_udp"},
1803dec9fcqs
1813dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1823dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1833dec9fcqs		"class-opt-ipv4-ah", "class_opt_ipv4_ah"},
1843dec9fcqs
1853dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1863dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1873dec9fcqs		"class-opt-ipv4-sctp", "class_opt_ipv4_sctp"},
1883dec9fcqs
1893dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1903dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1913dec9fcqs		"class-opt-ipv6-tcp", "class_opt_ipv6_tcp"},
1923dec9fcqs
1933dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1943dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1953dec9fcqs		"class-opt-ipv6-udp", "class_opt_ipv6_udp"},
1963dec9fcqs
1973dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
1983dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
1993dec9fcqs		"class-opt-ipv6-ah", "class_opt_ipv6_ah"},
2003dec9fcqs
2013dec9fcqs	{hxge_param_get_ip_opt, hxge_param_set_ip_opt, HXGE_PARAM_CLASS_RWS,
2023dec9fcqs		0, ALL_FF_32, HXGE_CLASS_TCAM_LOOKUP, 0,
2033dec9fcqs		"class-opt-ipv6-sctp", "class_opt_ipv6_sctp"},
2043dec9fcqs
2053dec9fcqs	{hxge_param_get_debug_flag, hxge_param_set_hxge_debug_flag,
2063dec9fcqs		HXGE_PARAM_RW | HXGE_PARAM_DONT_SHOW,
2073dec9fcqs		0ULL, ALL_FF_64, 0ULL, 0ULL,
2083dec9fcqs		"hxge-debug-flag", "hxge_debug_flag"},
2093dec9fcqs
2103dec9fcqs	{hxge_param_get_debug_flag, hxge_param_set_hpi_debug_flag,
2113dec9fcqs		HXGE_PARAM_RW | HXGE_PARAM_DONT_SHOW,
2123dec9fcqs		0ULL, ALL_FF_64, 0ULL, 0ULL,
2133dec9fcqs		"hpi-debug-flag", "hpi_debug_flag"},
2143dec9fcqs
2153dec9fcqs	{hxge_param_dump_ptrs, NULL, HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW,
2163dec9fcqs		0, 0x0fffffff, 0x0fffffff, 0, "dump-ptrs", "dump_ptrs"},
2173dec9fcqs
2183dec9fcqs	{NULL, NULL, HXGE_PARAM_READ | HXGE_PARAM_DONT_SHOW,
2193dec9fcqs		0, 0x0fffffff, 0x0fffffff, 0, "end", "end"},
2203dec9fcqs};
2213dec9fcqs
2223dec9fcqsextern void *hxge_list;
2233dec9fcqs
2243dec9fcqs/*
2253dec9fcqs * Update the NDD array from the soft properties.
2263dec9fcqs */
2273dec9fcqsvoid
2283dec9fcqshxge_get_param_soft_properties(p_hxge_t hxgep)
2293dec9fcqs{
2303dec9fcqs	p_hxge_param_t	param_arr;
2313dec9fcqs	uint_t		prop_len;
2323dec9fcqs	int		i, j;
2333dec9fcqs	uint32_t	param_count;
2343dec9fcqs	uint32_t	*int_prop_val;
2353dec9fcqs
2363dec9fcqs	HXGE_DEBUG_MSG((hxgep, DDI_CTL, " ==> hxge_get_param_soft_properties"));
2373dec9fcqs
2383dec9fcqs	param_arr = hxgep->param_arr;
2393dec9fcqs	param_count = hxgep->param_count;
2403dec9fcqs	for (i = 0; i < param_count; i++) {
2413dec9fcqs
2423dec9fcqs		if ((param_arr[i].type & HXGE_PARAM_READ_PROP) == 0)
2433dec9fcqs			continue;
2443dec9fcqs
2453dec9fcqs		if ((param_arr[i].type & HXGE_PARAM_PROP_STR))
2463dec9fcqs			continue;
2473dec9fcqs
2483dec9fcqs		if ((param_arr[i].type & HXGE_PARAM_PROP_ARR32) ||
2493dec9fcqs		    (param_arr[i].type & HXGE_PARAM_PROP_ARR64)) {
2503dec9fcqs
2513dec9fcqs			if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
2523dec9fcqs			    hxgep->dip, 0, param_arr[i].fcode_name,
2533dec9fcqs			    (int **)&int_prop_val, (uint_t *)&prop_len) ==
2543dec9fcqs			    DDI_PROP_SUCCESS) {
2553dec9fcqs				uint64_t *cfg_value;
2563dec9fcqs				uint64_t prop_count;
2573dec9fcqs
2583dec9fcqs				if (prop_len > HXGE_PARAM_ARRAY_INIT_SIZE)
2593dec9fcqs					prop_len = HXGE_PARAM_ARRAY_INIT_SIZE;
2603dec9fcqs#if defined(__i386)
2613dec9fcqs				cfg_value =
2623dec9fcqs				    (uint64_t *)(int32_t)param_arr[i].value;
2633dec9fcqs#else
2643dec9fcqs				cfg_value = (uint64_t *)param_arr[i].value;
2653dec9fcqs#endif
2663dec9fcqs				for (j = 0; j < prop_len; j++) {
2673dec9fcqs					cfg_value[j] = int_prop_val[j];
2683dec9fcqs				}
2693dec9fcqs				prop_count = prop_len;
2703dec9fcqs				param_arr[i].type |=
2713dec9fcqs				    (prop_count << HXGE_PARAM_ARRAY_CNT_SHIFT);
2723dec9fcqs
2733dec9fcqs				ddi_prop_free(int_prop_val);
2743dec9fcqs			}
2753dec9fcqs			continue;
2763dec9fcqs		}
2773dec9fcqs		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0,
2783dec9fcqs		    param_arr[i].fcode_name, (int **)&int_prop_val,
2793dec9fcqs		    &prop_len) == DDI_PROP_SUCCESS) {
2803dec9fcqs			if ((*int_prop_val >= param_arr[i].minimum) &&
2813dec9fcqs			    (*int_prop_val <= param_arr[i].maximum))
2823dec9fcqs				param_arr[i].value = *int_prop_val;
2833dec9fcqs			ddi_prop_free(int_prop_val);
2843dec9fcqs		}
2853dec9fcqs		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, hxgep->dip, 0,
2863dec9fcqs		    param_arr[i].name, (int **)&int_prop_val, &prop_len) ==
2873dec9fcqs		    DDI_PROP_SUCCESS) {
2883dec9fcqs			if ((*int_prop_val >= param_arr[i].minimum) &&
2893dec9fcqs			    (*int_prop_val <= param_arr[i].maximum))
2903dec9fcqs				param_arr[i].value = *int_prop_val;
2913dec9fcqs			ddi_prop_free(int_prop_val);
2923dec9fcqs		}
2933dec9fcqs	}
2943dec9fcqs}
2953dec9fcqs
2963dec9fcqsstatic int
2973dec9fcqshxge_private_param_register(p_hxge_t hxgep, p_hxge_param_t param_arr)
2983dec9fcqs{
2993dec9fcqs	int		status = B_TRUE;
3003dec9fcqs	int		channel;
3013dec9fcqs	char		*prop_name;
3023dec9fcqs	char		*end;
3033dec9fcqs	uint32_t	name_chars;
3043dec9fcqs
3053dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD2_CTL, " hxge_private_param_register %s",
3063dec9fcqs	    param_arr->name));
3073dec9fcqs
3083dec9fcqs	if ((param_arr->type & HXGE_PARAM_PRIV) != HXGE_PARAM_PRIV)
3093dec9fcqs		return (B_TRUE);
3103dec9fcqs	prop_name = param_arr->name;
3113dec9fcqs	if (param_arr->type & HXGE_PARAM_RXDMA) {
3123dec9fcqs		if (strncmp("rxdma_intr", prop_name, 10) == 0)
3133dec9fcqs			return (B_TRUE);
3143dec9fcqs		else
3153dec9fcqs			return (B_FALSE);
3163dec9fcqs	}
3173dec9fcqs
3183dec9fcqs	if (param_arr->type & HXGE_PARAM_TXDMA) {
3193dec9fcqs		name_chars = strlen("txdma");
3203dec9fcqs		if (strncmp("txdma", prop_name, name_chars) == 0) {
3213dec9fcqs			prop_name += name_chars;
3223dec9fcqs			channel = mi_strtol(prop_name, &end, 10);
3233dec9fcqs			/* now check if this rdc is in config */
3243dec9fcqs			HXGE_DEBUG_MSG((hxgep, NDD2_CTL,
3253dec9fcqs			    " hxge_private_param_register: %d", channel));
3263dec9fcqs			return (hxge_check_txdma_port_member(hxgep, channel));
3273dec9fcqs		}
3283dec9fcqs		return (B_FALSE);
3293dec9fcqs	}
3303dec9fcqs
3313dec9fcqs	status = B_FALSE;
3323dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD2_CTL, "<== hxge_private_param_register"));
3333dec9fcqs
3343dec9fcqs	return (status);
3353dec9fcqs}
3363dec9fcqs
3373dec9fcqsvoid
3383dec9fcqshxge_setup_param(p_hxge_t hxgep)
3393dec9fcqs{
3403dec9fcqs	p_hxge_param_t	param_arr;
3413dec9fcqs	int		i;
3423dec9fcqs	pfi_t		set_pfi;
3433dec9fcqs
3443dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_setup_param"));
3453dec9fcqs	/*
3463dec9fcqs	 * Make sure the param_instance is set to a valid device instance.
3473dec9fcqs	 */
3483dec9fcqs	if (hxge_param_arr[param_instance].value == 1000)
3493dec9fcqs		hxge_param_arr[param_instance].value = hxgep->instance;
3503dec9fcqs
3513dec9fcqs	param_arr = hxgep->param_arr;
3523dec9fcqs	param_arr[param_instance].value = hxgep->instance;
3533dec9fcqs
3543dec9fcqs	for (i = 0; i < hxgep->param_count; i++) {
3553dec9fcqs		if ((param_arr[i].type & HXGE_PARAM_PRIV) &&
3563dec9fcqs		    (hxge_private_param_register(hxgep, &param_arr[i]) ==
3573dec9fcqs		    B_FALSE)) {
3583dec9fcqs			param_arr[i].setf = NULL;
3593dec9fcqs			param_arr[i].getf = NULL;
3603dec9fcqs		}
3613dec9fcqs		if (param_arr[i].type & HXGE_PARAM_CMPLX)
3623dec9fcqs			param_arr[i].setf = NULL;
3633dec9fcqs
3643dec9fcqs		if (param_arr[i].type & HXGE_PARAM_DONT_SHOW) {
3653dec9fcqs			param_arr[i].setf = NULL;
3663dec9fcqs			param_arr[i].getf = NULL;
3673dec9fcqs		}
3683dec9fcqs		set_pfi = (pfi_t)param_arr[i].setf;
3693dec9fcqs
3703dec9fcqs		if ((set_pfi) && (param_arr[i].type & HXGE_PARAM_INIT_ONLY)) {
3713dec9fcqs			set_pfi = NULL;
3723dec9fcqs		}
3733dec9fcqs		if (!hxge_nd_load(&hxgep->param_list, param_arr[i].name,
3743dec9fcqs		    (pfi_t)param_arr[i].getf, set_pfi,
3753dec9fcqs		    (caddr_t)&param_arr[i])) {
3763dec9fcqs			(void) hxge_nd_free(&hxgep->param_list);
3773dec9fcqs			break;
3783dec9fcqs		}
3793dec9fcqs	}
3803dec9fcqs
3813dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_setup_param"));
3823dec9fcqs}
3833dec9fcqs
3843dec9fcqs/*
3853dec9fcqs * Called from the attached function, it allocates memory for
3863dec9fcqs * the parameter array and some members.
3873dec9fcqs */
3883dec9fcqsvoid
3893dec9fcqshxge_init_param(p_hxge_t hxgep)
3903dec9fcqs{
3913dec9fcqs	p_hxge_param_t	param_arr;
3923dec9fcqs	int		i, alloc_size;
3933dec9fcqs	uint64_t	alloc_count;
3943dec9fcqs
3953dec9fcqs	HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_init_param"));
3963dec9fcqs	/*
3973dec9fcqs	 * Make sure the param_instance is set to a valid device instance.
3983dec9fcqs	 */
3993dec9fcqs	if (hxge_param_arr[param_instance].value == 1000)
4003dec9fcqs		hxge_param_arr[param_instance].value = hxgep->instance;
4013dec9fcqs
4023dec9fcqs	param_arr = hxgep->param_arr;
4033dec9fcqs	if (param_arr == NULL) {
4043dec9fcqs		param_arr = (p_hxge_param_t)KMEM_ZALLOC(
4053dec9fcqs		    sizeof (hxge_param_arr), KM_SLEEP);
4063dec9fcqs	}
4073dec9fcqs	for (i = 0; i < sizeof (hxge_param_arr) / sizeof (hxge_param_t); i++) {
4083dec9fcqs		param_arr[i] = hxge_param_arr[i];
4093dec9fcqs		if ((param_arr[i].type & HXGE_PARAM_PROP_ARR32) ||
4103dec9fcqs		    (param_arr[i].type & HXGE_PARAM_PROP_ARR64)) {
4113dec9fcqs			alloc_count = HXGE_PARAM_ARRAY_INIT_SIZE;
4123dec9fcqs			alloc_size = alloc_count * sizeof (uint64_t);
4133dec9fcqs#if defined(__i386)
4143dec9fcqs			param_arr[i].value =
4153dec9fcqs			    (uint64_t)(uint32_t)KMEM_ZALLOC(alloc_size,
4163dec9fcqs			    KM_SLEEP);
4173dec9fcqs			param_arr[i].old_value =
4183dec9fcqs			    (uint64_t)(uint32_t)KMEM_ZALLOC(alloc_size,
4193dec9fcqs			    KM_SLEEP);
4203dec9fcqs#else
4213dec9fcqs			param_arr[i].value =
4223dec9fcqs			    (uint64_t)KMEM_ZALLOC(alloc_size, KM_SLEEP);
4233dec9fcqs			param_arr[i].old_value =
4243dec9fcqs			    (uint64_t)KMEM_ZALLOC(alloc_size, KM_SLEEP);
4253dec9fcqs#endif
4263dec9fcqs			param_arr[i].type |=
4273dec9fcqs			    (alloc_count << HXGE_PARAM_ARRAY_ALLOC_SHIFT);
4283dec9fcqs		}
4293dec9fcqs	}
4303dec9fcqs
4313dec9fcqs	hxgep->param_arr = param_arr;
4323dec9fcqs	hxgep->param_count = sizeof (hxge_param_arr) / sizeof (hxge_param_t);
4333dec9fcqs	HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_init_param: count %d",
4343dec9fcqs	    hxgep->param_count));
4353dec9fcqs}
4363dec9fcqs
4373dec9fcqs/*
4383dec9fcqs * Called from the attached functions, it frees memory for the parameter array
4393dec9fcqs */
4403dec9fcqsvoid
4413dec9fcqshxge_destroy_param(p_hxge_t hxgep)
4423dec9fcqs{
4433dec9fcqs	int		i;
4443dec9fcqs	uint64_t	free_size, free_count;
4453dec9fcqs
4463dec9fcqs	HXGE_DEBUG_MSG((hxgep, DDI_CTL, "==> hxge_destroy_param"));
4473dec9fcqs	/*
4483dec9fcqs	 * Make sure the param_instance is set to a valid device instance.
4493dec9fcqs	 */
4503dec9fcqs	if (hxge_param_arr[param_instance].value == hxgep->instance) {
4513dec9fcqs		for (i = 0; i <= hxge_param_arr[param_instance].maximum; i++) {
4523dec9fcqs			if ((ddi_get_soft_state(hxge_list, i) != NULL) &&
4533dec9fcqs			    (i != hxgep->instance))
4543dec9fcqs				break;
4553dec9fcqs		}
4563dec9fcqs		hxge_param_arr[param_instance].value = i;
4573dec9fcqs	}
4583dec9fcqs	if (hxgep->param_list)
4593dec9fcqs		hxge_nd_free(&hxgep->param_list);
4603dec9fcqs	for (i = 0; i < hxgep->param_count; i++) {
4613dec9fcqs		if ((hxgep->param_arr[i].type & HXGE_PARAM_PROP_ARR32) ||
4623dec9fcqs		    (hxgep->param_arr[i].type & HXGE_PARAM_PROP_ARR64)) {
4633dec9fcqs			free_count = ((hxgep->param_arr[i].type &
4643dec9fcqs			    HXGE_PARAM_ARRAY_ALLOC_MASK) >>
4653dec9fcqs			    HXGE_PARAM_ARRAY_ALLOC_SHIFT);
4663dec9fcqs			free_count = HXGE_PARAM_ARRAY_INIT_SIZE;
4673dec9fcqs			free_size = sizeof (uint64_t) * free_count;
4683dec9fcqs#if defined(__i386)
4693dec9fcqs			KMEM_FREE((void *)(uint32_t)
4703dec9fcqs			    hxgep->param_arr[i].value, free_size);
4713dec9fcqs			KMEM_FREE((void *)(uint32_t)
4723dec9fcqs			    hxgep->param_arr[i].old_value, free_size);
4733dec9fcqs#else
4743dec9fcqs			KMEM_FREE((void *) hxgep->param_arr[i].value,
4753dec9fcqs			    free_size);
4763dec9fcqs			KMEM_FREE((void *) hxgep->param_arr[i].old_value,
4773dec9fcqs			    free_size);
4783dec9fcqs#endif
4793dec9fcqs		}
4803dec9fcqs	}
4813dec9fcqs
4823dec9fcqs	KMEM_FREE(hxgep->param_arr, sizeof (hxge_param_arr));
4833dec9fcqs	HXGE_DEBUG_MSG((hxgep, DDI_CTL, "<== hxge_destroy_param"));
4843dec9fcqs}
4853dec9fcqs
4863dec9fcqs/*
4873dec9fcqs * Extracts the value from the 'hxge' parameter array and prints the
4883dec9fcqs * parameter value. cp points to the required parameter.
4893dec9fcqs */
4903dec9fcqs/* ARGSUSED */
4913dec9fcqsint
4923dec9fcqshxge_param_get_generic(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
4933dec9fcqs{
4943dec9fcqs	p_hxge_param_t pa = (p_hxge_param_t)cp;
4953dec9fcqs
4963dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, " ==> hxge_param_get_generic name %s ",
4973dec9fcqs	    pa->name));
4983dec9fcqs
4993dec9fcqs	if (pa->value > 0xffffffff)
5003dec9fcqs		(void) mi_mpprintf(mp, "%x%x", (int)(pa->value >> 32),
5013dec9fcqs		    (int)(pa->value & 0xffffffff));
5023dec9fcqs	else
5033dec9fcqs		(void) mi_mpprintf(mp, "%x", (int)pa->value);
5043dec9fcqs
5053dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_generic"));
5063dec9fcqs	return (0);
5073dec9fcqs}
5083dec9fcqs
5093dec9fcqs/* ARGSUSED */
5103dec9fcqsstatic int
5113dec9fcqshxge_param_get_mac(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
5123dec9fcqs{
5133dec9fcqs	p_hxge_param_t pa = (p_hxge_param_t)cp;
5143dec9fcqs
5153dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_mac"));
5163dec9fcqs
5173dec9fcqs	(void) mi_mpprintf(mp, "%d", (uint32_t)pa->value);
5183dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_mac"));
5193dec9fcqs	return (0);
5203dec9fcqs}
5213dec9fcqs
5223dec9fcqs/* ARGSUSED */
5233dec9fcqsint
5243dec9fcqshxge_param_get_rxdma_info(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
5253dec9fcqs{
5263dec9fcqs	uint_t			print_len, buf_len;
5273dec9fcqs	p_mblk_t		np;
5283dec9fcqs	int			rdc;
5293dec9fcqs	p_hxge_dma_pt_cfg_t	p_dma_cfgp;
5303dec9fcqs	p_hxge_hw_pt_cfg_t	p_cfgp;
5313dec9fcqs	int			buff_alloc_size = HXGE_NDD_INFODUMP_BUFF_SIZE;
5323dec9fcqs
5333dec9fcqs	p_rx_rcr_rings_t rx_rcr_rings;
5343dec9fcqs	p_rx_rcr_ring_t *rcr_rings;
5353dec9fcqs	p_rx_rbr_rings_t rx_rbr_rings;
5363dec9fcqs	p_rx_rbr_ring_t *rbr_rings;
5373dec9fcqs
5383dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_rxdma_info"));
5393dec9fcqs
5403dec9fcqs	(void) mi_mpprintf(mp, "RXDMA Information\n");
5413dec9fcqs
5423dec9fcqs	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
5433dec9fcqs		/* The following may work even if we cannot get a large buf. */
5443dec9fcqs		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
5453dec9fcqs		return (0);
5463dec9fcqs	}
5473dec9fcqs	buf_len = buff_alloc_size;
5483dec9fcqs
5493dec9fcqs	mp->b_cont = np;
5503dec9fcqs
5513dec9fcqs	p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
5523dec9fcqs	p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
5533dec9fcqs
5543dec9fcqs	rx_rcr_rings = hxgep->rx_rcr_rings;
5553dec9fcqs	rcr_rings = rx_rcr_rings->rcr_rings;
5563dec9fcqs	rx_rbr_rings = hxgep->rx_rbr_rings;
5573dec9fcqs	rbr_rings = rx_rbr_rings->rbr_rings;
5583dec9fcqs
5593dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
5603dec9fcqs	    "Total RDCs\t %d\n", p_cfgp->max_rdcs);
5613dec9fcqs	((mblk_t *)np)->b_wptr += print_len;
5623dec9fcqs	buf_len -= print_len;
5633dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
5643dec9fcqs	    "RDC\t HW RDC\t Timeout\t Packets RBR ptr \t"
5653dec9fcqs	    "chunks\t RCR ptr\n");
5663dec9fcqs	((mblk_t *)np)->b_wptr += print_len;
5673dec9fcqs	buf_len -= print_len;
5683dec9fcqs	for (rdc = 0; rdc < p_cfgp->max_rdcs; rdc++) {
5693dec9fcqs		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
5703dec9fcqs		    " %d\t  %d\t $%p\t 0x%x\t $%p\n",
5711667122Michael Speer		    rdc, hxgep->rdc[rdc], (void *)rbr_rings[rdc],
5721667122Michael Speer		    rbr_rings[rdc]->num_blocks, (void *)rcr_rings[rdc]);
5733dec9fcqs		((mblk_t *)np)->b_wptr += print_len;
5743dec9fcqs		buf_len -= print_len;
5753dec9fcqs	}
5763dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_rxdma_info"));
5773dec9fcqs	return (0);
5783dec9fcqs}
5793dec9fcqs
5803dec9fcqsint
5813dec9fcqshxge_mk_mblk_tail_space(p_mblk_t mp, p_mblk_t *nmp, size_t size)
5823dec9fcqs{
5833dec9fcqs	p_mblk_t tmp;
5843dec9fcqs
5853dec9fcqs	tmp = mp;
5863dec9fcqs	while (tmp->b_cont)
5873dec9fcqs		tmp = tmp->b_cont;
5883dec9fcqs	if ((tmp->b_wptr + size) >= tmp->b_datap->db_lim) {
5893dec9fcqs		tmp->b_cont = allocb(1024, BPRI_HI);
5903dec9fcqs		tmp = tmp->b_cont;
5913dec9fcqs		if (!tmp)
5923dec9fcqs			return (ENOMEM);
5933dec9fcqs	}
5943dec9fcqs	*nmp = tmp;
5953dec9fcqs	return (0);
5963dec9fcqs}
5973dec9fcqs
5983dec9fcqs/*
5993dec9fcqs * Sets the ge parameter to the value in the hxge_param_register using
6003dec9fcqs * hxge_nd_load().
6013dec9fcqs */
6023dec9fcqs/* ARGSUSED */
6033dec9fcqsint
6043dec9fcqshxge_param_set_generic(p_hxge_t hxgep, queue_t *q, mblk_t *mp,
6053dec9fcqs	char *value, caddr_t cp)
6063dec9fcqs{
6073dec9fcqs	char		*end;
6083dec9fcqs	uint32_t	new_value;
6093dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
6103dec9fcqs
6113dec9fcqs	HXGE_DEBUG_MSG((hxgep, IOC_CTL, " ==> hxge_param_set_generic"));
6123dec9fcqs	new_value = (uint32_t)mi_strtol(value, &end, 10);
6133dec9fcqs	if (end == value || new_value < pa->minimum ||
6143dec9fcqs	    new_value > pa->maximum) {
6153dec9fcqs		return (EINVAL);
6163dec9fcqs	}
6173dec9fcqs	pa->value = new_value;
6183dec9fcqs	HXGE_DEBUG_MSG((hxgep, IOC_CTL, " <== hxge_param_set_generic"));
6193dec9fcqs	return (0);
6203dec9fcqs}
6213dec9fcqs
6223dec9fcqs/* ARGSUSED */
6233dec9fcqsint
6243dec9fcqshxge_param_set_mac(p_hxge_t hxgep, queue_t *q, mblk_t *mp,
6253dec9fcqs	char *value, caddr_t cp)
6263dec9fcqs{
6273dec9fcqs	char		*end;
6283dec9fcqs	uint32_t	new_value;
6293dec9fcqs	int		status = 0;
6303dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
6313dec9fcqs
6323dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_mac"));
6333dec9fcqs	new_value = (uint32_t)mi_strtol(value, &end, BASE_DECIMAL);
6343dec9fcqs	if (PARAM_OUTOF_RANGE(value, end, new_value, pa)) {
6353dec9fcqs		return (EINVAL);
6363dec9fcqs	}
6373dec9fcqs
6383dec9fcqs	if (pa->value != new_value) {
6393dec9fcqs		pa->old_value = pa->value;
6403dec9fcqs		pa->value = new_value;
6413dec9fcqs	}
6423dec9fcqs
6433dec9fcqs	if (pa->value != pa->old_value) {
6443dec9fcqs		RW_ENTER_WRITER(&hxgep->filter_lock);
6453dec9fcqs		(void) hxge_rx_vmac_disable(hxgep);
6463dec9fcqs		(void) hxge_tx_vmac_disable(hxgep);
6473dec9fcqs
6483dec9fcqs		/*
6493dec9fcqs		 * Apply the new jumbo parameter here.
6503dec9fcqs		 * The order of the following two calls is important.
6513dec9fcqs		 */
6523dec9fcqs		(void) hxge_tx_vmac_enable(hxgep);
6533dec9fcqs		(void) hxge_rx_vmac_enable(hxgep);
6543dec9fcqs		RW_EXIT(&hxgep->filter_lock);
6553dec9fcqs	}
6563dec9fcqs
6573dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_mac"));
6583dec9fcqs	return (status);
6593dec9fcqs}
6603dec9fcqs
6613dec9fcqs/* ARGSUSED */
662a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint
6633dec9fcqshxge_param_rx_intr_pkts(p_hxge_t hxgep, queue_t *q,
6643dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
6653dec9fcqs{
6663dec9fcqs	char		*end;
6673dec9fcqs	uint32_t	cfg_value;
6683dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
6693dec9fcqs
6703dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_rx_intr_pkts"));
6713dec9fcqs
672a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
673a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
674a512c5dQiyan Sun - Sun Microsystems - San Diego United States
675a512c5dQiyan Sun - Sun Microsystems - San Diego United States	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
6763dec9fcqs
6773dec9fcqs	if ((cfg_value > HXGE_RDC_RCR_THRESHOLD_MAX) ||
6783dec9fcqs	    (cfg_value < HXGE_RDC_RCR_THRESHOLD_MIN)) {
6793dec9fcqs		return (EINVAL);
6803dec9fcqs	}
6813dec9fcqs
6823dec9fcqs	if ((pa->value != cfg_value)) {
6833dec9fcqs		pa->old_value = pa->value;
6843dec9fcqs		pa->value = cfg_value;
6853dec9fcqs		hxgep->intr_threshold = pa->value;
6863dec9fcqs	}
6873dec9fcqs
6883dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_rx_intr_pkts"));
6893dec9fcqs	return (0);
6903dec9fcqs}
6913dec9fcqs
6923dec9fcqs/* ARGSUSED */
693a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint
6943dec9fcqshxge_param_rx_intr_time(p_hxge_t hxgep, queue_t *q,
6953dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
6963dec9fcqs{
6973dec9fcqs	char		*end;
6983dec9fcqs	uint32_t	cfg_value;
6993dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
7003dec9fcqs
7013dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_rx_intr_time"));
7023dec9fcqs
703a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
704a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
705a512c5dQiyan Sun - Sun Microsystems - San Diego United States
706a512c5dQiyan Sun - Sun Microsystems - San Diego United States	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
7073dec9fcqs
7083dec9fcqs	if ((cfg_value > HXGE_RDC_RCR_TIMEOUT_MAX) ||
7093dec9fcqs	    (cfg_value < HXGE_RDC_RCR_TIMEOUT_MIN)) {
7103dec9fcqs		return (EINVAL);
7113dec9fcqs	}
7123dec9fcqs
7133dec9fcqs	if ((pa->value != cfg_value)) {
7143dec9fcqs		pa->old_value = pa->value;
7153dec9fcqs		pa->value = cfg_value;
7163dec9fcqs		hxgep->intr_timeout = pa->value;
7173dec9fcqs	}
7183dec9fcqs
7193dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_rx_intr_time"));
7203dec9fcqs	return (0);
7213dec9fcqs}
7223dec9fcqs
7233dec9fcqs/* ARGSUSED */
7243dec9fcqsstatic int
7253dec9fcqshxge_param_set_vlan_ids(p_hxge_t hxgep, queue_t *q, mblk_t *mp, char *value,
7263dec9fcqs    caddr_t cp)
7273dec9fcqs{
7283dec9fcqs	char			*end;
7293dec9fcqs	uint32_t		status = 0, cfg_value;
7303dec9fcqs	p_hxge_param_t		pa = (p_hxge_param_t)cp;
7313dec9fcqs	uint32_t		cfg_it = B_FALSE;
7323dec9fcqs	uint32_t		*val_ptr, *old_val_ptr;
7333dec9fcqs	hxge_param_map_t	*vmap, *old_map;
7343dec9fcqs	p_hxge_class_pt_cfg_t 	p_class_cfgp;
7353dec9fcqs	uint64_t		cfgd_vlans;
7363dec9fcqs	int			i, inc = 0, cfg_position;
7373dec9fcqs	hxge_mv_cfg_t		*vlan_tbl;
7383dec9fcqs	hpi_handle_t		handle;
7393dec9fcqs
7403dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_vlan_ids "));
7413dec9fcqs
7423dec9fcqs	p_class_cfgp = (p_hxge_class_pt_cfg_t)&hxgep->class_config;
7433dec9fcqs	vlan_tbl = (hxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0];
7443dec9fcqs	handle = hxgep->hpi_reg_handle;
7453dec9fcqs
746a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
747a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
748a512c5dQiyan Sun - Sun Microsystems - San Diego United States
7493dec9fcqs	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
7503dec9fcqs
7513dec9fcqs	/* now do decoding */
7523dec9fcqs	cfgd_vlans = ((pa->type & HXGE_PARAM_ARRAY_CNT_MASK) >>
7533dec9fcqs	    HXGE_PARAM_ARRAY_CNT_SHIFT);
7543dec9fcqs
7553dec9fcqs	if (cfgd_vlans >= HXGE_PARAM_ARRAY_INIT_SIZE) {
7563dec9fcqs		/*
7573dec9fcqs		 * for now, we process only upto HXGE_PARAM_ARRAY_INIT_SIZE
7583dec9fcqs		 * parameters In the future, we may want to expand
7593dec9fcqs		 * the storage array and continue
7603dec9fcqs		 */
7613dec9fcqs		return (EINVAL);
7623dec9fcqs	}
7633dec9fcqs
7643dec9fcqs	vmap = (hxge_param_map_t *)&cfg_value;
7653dec9fcqs	if ((vmap->param_id == 0) || (vmap->param_id > VLAN_ID_MAX)) {
7663dec9fcqs		return (EINVAL);
7673dec9fcqs	}
7683dec9fcqs
7693dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, " hxge_param_set_vlan_ids id %d",
7703dec9fcqs	    vmap->param_id));
7713dec9fcqs#if defined(__i386)
7723dec9fcqs	val_ptr = (uint32_t *)(uint32_t)pa->value;
7733dec9fcqs	old_val_ptr = (uint32_t *)(uint32_t)pa->old_value;
7743dec9fcqs#else
7753dec9fcqs	val_ptr = (uint32_t *)pa->value;
7763dec9fcqs	old_val_ptr = (uint32_t *)pa->old_value;
7773dec9fcqs#endif
7783dec9fcqs
7793dec9fcqs	/* Search to see if this vlan id is already configured */
7803dec9fcqs	for (i = 0; i < cfgd_vlans; i++) {
7813dec9fcqs		old_map = (hxge_param_map_t *)&val_ptr[i];
7823dec9fcqs		if ((old_map->param_id == 0) ||
7833dec9fcqs		    (vmap->param_id == old_map->param_id) ||
7843dec9fcqs		    (vlan_tbl[vmap->param_id].flag)) {
7853dec9fcqs			cfg_position = i;
7863dec9fcqs			break;
7873dec9fcqs		}
7883dec9fcqs	}
7893dec9fcqs
7903dec9fcqs	if (cfgd_vlans == 0) {
7913dec9fcqs		cfg_position = 0;
7923dec9fcqs		inc++;
7933dec9fcqs	}
7943dec9fcqs
7953dec9fcqs	if (i == cfgd_vlans) {
7963dec9fcqs		cfg_position = i;
7973dec9fcqs		inc++;
7983dec9fcqs	}
7993dec9fcqs
8003dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD2_CTL,
8013dec9fcqs	    " set_vlan_ids mapping i %d cfgd_vlans %llx position %d ",
8023dec9fcqs	    i, cfgd_vlans, cfg_position));
8033dec9fcqs
8043dec9fcqs	if (val_ptr[cfg_position] != cfg_value) {
8053dec9fcqs		old_val_ptr[cfg_position] = val_ptr[cfg_position];
8063dec9fcqs		val_ptr[cfg_position] = cfg_value;
8073dec9fcqs		vlan_tbl[vmap->param_id].flag = 1;
8083dec9fcqs		cfg_it = B_TRUE;
8093dec9fcqs		if (inc) {
8103dec9fcqs			cfgd_vlans++;
8113dec9fcqs			pa->type &= ~HXGE_PARAM_ARRAY_CNT_MASK;
8123dec9fcqs			pa->type |= (cfgd_vlans << HXGE_PARAM_ARRAY_CNT_SHIFT);
8133dec9fcqs
8143dec9fcqs		}
8153dec9fcqs
8163dec9fcqs		HXGE_DEBUG_MSG((hxgep, NDD2_CTL,
8173dec9fcqs		    " after: param_set_vlan_ids cfg_vlans %llx position %d \n",
8183dec9fcqs		    cfgd_vlans, cfg_position));
8193dec9fcqs	}
8203dec9fcqs
8213dec9fcqs	if (cfg_it == B_TRUE) {
8223dec9fcqs		status = hpi_pfc_cfg_vlan_table_entry_set(handle,
8233dec9fcqs		    (vlan_id_t)vmap->param_id);
8243dec9fcqs		if (status != HPI_SUCCESS)
8253dec9fcqs			return (EINVAL);
8263dec9fcqs	}
8273dec9fcqs
8283dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_vlan_ids"));
8293dec9fcqs
8303dec9fcqs	return (0);
8313dec9fcqs}
8323dec9fcqs
8333dec9fcqs
8343dec9fcqs/* ARGSUSED */
8353dec9fcqsstatic int
8363dec9fcqshxge_param_get_vlan_ids(p_hxge_t hxgep, queue_t *q, mblk_t *mp, caddr_t cp)
8373dec9fcqs{
8383dec9fcqs	uint_t			print_len, buf_len;
8393dec9fcqs	p_mblk_t		np;
8403dec9fcqs	int			i;
8413dec9fcqs	uint32_t		*val_ptr;
8423dec9fcqs	hxge_param_map_t	*vmap;
8433dec9fcqs	p_hxge_param_t		pa = (p_hxge_param_t)cp;
8443dec9fcqs	p_hxge_class_pt_cfg_t 	p_class_cfgp;
8453dec9fcqs	uint64_t		cfgd_vlans = 0;
8463dec9fcqs	int buff_alloc_size = HXGE_NDD_INFODUMP_BUFF_SIZE * 32;
8473dec9fcqs
8483dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_vlan_ids "));
8493dec9fcqs	(void) mi_mpprintf(mp, "VLAN Information\n");
8503dec9fcqs
8513dec9fcqs	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
8523dec9fcqs		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
8533dec9fcqs		return (0);
8543dec9fcqs	}
8553dec9fcqs
8563dec9fcqs	buf_len = buff_alloc_size;
8573dec9fcqs	mp->b_cont = np;
8583dec9fcqs	cfgd_vlans = (pa->type & HXGE_PARAM_ARRAY_CNT_MASK) >>
8593dec9fcqs	    HXGE_PARAM_ARRAY_CNT_SHIFT;
8603dec9fcqs
8613dec9fcqs	i = (int)cfgd_vlans;
8623dec9fcqs	p_class_cfgp = (p_hxge_class_pt_cfg_t)&hxgep->class_config;
8633dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
8643dec9fcqs	    "Configured VLANs %d\n VLAN ID\n", i);
8653dec9fcqs	((mblk_t *)np)->b_wptr += print_len;
8663dec9fcqs	buf_len -= print_len;
8673dec9fcqs
8683dec9fcqs#if defined(__i386)
8693dec9fcqs	val_ptr = (uint32_t *)(uint32_t)pa->value;
8703dec9fcqs#else
8713dec9fcqs	val_ptr = (uint32_t *)pa->value;
8723dec9fcqs#endif
8733dec9fcqs
8743dec9fcqs	for (i = 0; i < cfgd_vlans; i++) {
8753dec9fcqs		vmap = (hxge_param_map_t *)&val_ptr[i];
8763dec9fcqs		if (p_class_cfgp->vlan_tbl[vmap->param_id].flag) {
8773dec9fcqs			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
8783dec9fcqs			    buf_len, "  %d\n", vmap->param_id);
8793dec9fcqs			((mblk_t *)np)->b_wptr += print_len;
8803dec9fcqs			buf_len -= print_len;
8813dec9fcqs		}
8823dec9fcqs	}
8833dec9fcqs
8843dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_vlan_ids"));
8853dec9fcqs
8863dec9fcqs	return (0);
8873dec9fcqs}
8883dec9fcqs
8893dec9fcqs/* ARGSUSED */
8903dec9fcqsstatic int
8913dec9fcqshxge_param_tcam_enable(p_hxge_t hxgep, queue_t *q,
8923dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
8933dec9fcqs{
8943dec9fcqs	uint32_t	status = 0, cfg_value;
8953dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
8963dec9fcqs	uint32_t	cfg_it = B_FALSE;
8973dec9fcqs	char		*end;
8983dec9fcqs
8993dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_tcam_enable"));
9003dec9fcqs
9013dec9fcqs	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_BINARY);
9023dec9fcqs	if (pa->value != cfg_value) {
9033dec9fcqs		pa->old_value = pa->value;
9043dec9fcqs		pa->value = cfg_value;
9053dec9fcqs		cfg_it = B_TRUE;
9063dec9fcqs	}
9073dec9fcqs	if (cfg_it == B_TRUE) {
9083dec9fcqs		if (pa->value)
9093dec9fcqs			status = hxge_pfc_config_tcam_enable(hxgep);
9103dec9fcqs		else
9113dec9fcqs			status = hxge_pfc_config_tcam_disable(hxgep);
9123dec9fcqs		if (status != HXGE_OK)
9133dec9fcqs			return (EINVAL);
9143dec9fcqs	}
9153dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, " <== hxge_param_tcam_enable"));
9163dec9fcqs	return (0);
9173dec9fcqs}
9183dec9fcqs
9193dec9fcqs/* ARGSUSED */
9203dec9fcqsstatic int
9213dec9fcqshxge_param_set_ether_usr(p_hxge_t hxgep, queue_t *q,
9223dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
9233dec9fcqs{
9243dec9fcqs	char		*end;
9253dec9fcqs	uint32_t	status = 0, cfg_value;
9263dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
9273dec9fcqs
9283dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_ether_usr"));
9293dec9fcqs
930a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
931a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
932a512c5dQiyan Sun - Sun Microsystems - San Diego United States
9333dec9fcqs	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
9343dec9fcqs	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
9353dec9fcqs		return (EINVAL);
9363dec9fcqs	}
9373dec9fcqs	if (pa->value != cfg_value) {
9383dec9fcqs		pa->old_value = pa->value;
9393dec9fcqs		pa->value = cfg_value;
9403dec9fcqs	}
9413dec9fcqs
9423dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_ether_usr"));
9433dec9fcqs	return (status);
9443dec9fcqs}
9453dec9fcqs
9463dec9fcqsstatic int
9473dec9fcqshxge_class_name_2value(p_hxge_t hxgep, char *name)
9483dec9fcqs{
9493dec9fcqs	int		i;
9503dec9fcqs	int		class_instance = param_class_opt_ipv4_tcp;
9513dec9fcqs	p_hxge_param_t	param_arr;
9523dec9fcqs
9533dec9fcqs	param_arr = hxgep->param_arr;
9543dec9fcqs	for (i = TCAM_CLASS_TCP_IPV4; i <= TCAM_CLASS_SCTP_IPV6; i++) {
9553dec9fcqs		if (strcmp(param_arr[class_instance].name, name) == 0)
9563dec9fcqs			return (i);
9573dec9fcqs		class_instance++;
9583dec9fcqs	}
9593dec9fcqs	return (-1);
9603dec9fcqs}
9613dec9fcqs
9623dec9fcqs/* ARGSUSED */
963a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint
9643dec9fcqshxge_param_set_ip_opt(p_hxge_t hxgep, queue_t *q,
9653dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
9663dec9fcqs{
9673dec9fcqs	char		*end;
9683dec9fcqs	uint32_t	status, cfg_value;
9693dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
9703dec9fcqs	tcam_class_t	class;
9713dec9fcqs	uint32_t	cfg_it = B_FALSE;
9723dec9fcqs
9733dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_ip_opt"));
9743dec9fcqs
975a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
976a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
977a512c5dQiyan Sun - Sun Microsystems - San Diego United States
9783dec9fcqs	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
9793dec9fcqs	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
9803dec9fcqs		return (EINVAL);
9813dec9fcqs	}
9823dec9fcqs	if (pa->value != cfg_value) {
9833dec9fcqs		pa->old_value = pa->value;
9843dec9fcqs		pa->value = cfg_value;
9853dec9fcqs		cfg_it = B_TRUE;
9863dec9fcqs	}
9873dec9fcqs	if (cfg_it == B_TRUE) {
9883dec9fcqs		/* do the actual hw setup  */
9893dec9fcqs		class = hxge_class_name_2value(hxgep, pa->name);
9903dec9fcqs		if (class == -1)
9913dec9fcqs			return (EINVAL);
9923dec9fcqs
9933dec9fcqs		status = hxge_pfc_ip_class_config(hxgep, class, pa->value);
9943dec9fcqs		if (status != HXGE_OK)
9953dec9fcqs			return (EINVAL);
9963dec9fcqs	}
9973dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_ip_opt"));
9983dec9fcqs	return (0);
9993dec9fcqs}
10003dec9fcqs
10013dec9fcqs/* ARGSUSED */
1002a512c5dQiyan Sun - Sun Microsystems - San Diego United Statesint
10033dec9fcqshxge_param_get_ip_opt(p_hxge_t hxgep, queue_t *q, mblk_t *mp, caddr_t cp)
10043dec9fcqs{
10053dec9fcqs	uint32_t	status, cfg_value;
10063dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
10073dec9fcqs	tcam_class_t	class;
10083dec9fcqs
10093dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_ip_opt"));
10103dec9fcqs
10113dec9fcqs	/* do the actual hw setup  */
10123dec9fcqs	class = hxge_class_name_2value(hxgep, pa->name);
10133dec9fcqs	if (class == -1)
10143dec9fcqs		return (EINVAL);
10153dec9fcqs	cfg_value = 0;
10163dec9fcqs	status = hxge_pfc_ip_class_config_get(hxgep, class, &cfg_value);
10173dec9fcqs	if (status != HXGE_OK)
10183dec9fcqs		return (EINVAL);
10193dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL,
10203dec9fcqs	    "hxge_param_get_ip_opt_get %x ", cfg_value));
10213dec9fcqs	pa->value = cfg_value;
10223dec9fcqs
1023a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (mp != NULL)
1024a512c5dQiyan Sun - Sun Microsystems - San Diego United States		(void) mi_mpprintf(mp, "%x", cfg_value);
1025a512c5dQiyan Sun - Sun Microsystems - San Diego United States
10263dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_ip_opt status "));
10273dec9fcqs	return (0);
10283dec9fcqs}
10293dec9fcqs
10303dec9fcqs/* ARGSUSED */
10313dec9fcqsstatic int
10323dec9fcqshxge_param_pfc_hash_init(p_hxge_t hxgep, queue_t *q, mblk_t *mp,
10333dec9fcqs	char *value, caddr_t cp)
10343dec9fcqs{
10353dec9fcqs	char		*end;
10363dec9fcqs	uint32_t	status, cfg_value;
10373dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
10383dec9fcqs	uint32_t	cfg_it = B_FALSE;
10393dec9fcqs
10403dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_pfc_hash_init"));
10413dec9fcqs
1042a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
1043a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
1044a512c5dQiyan Sun - Sun Microsystems - San Diego United States
10453dec9fcqs	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
10463dec9fcqs	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
10473dec9fcqs		return (EINVAL);
10483dec9fcqs	}
10493dec9fcqs
10503dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL,
10513dec9fcqs	    " hxge_param_pfc_hash_init value %x", cfg_value));
10523dec9fcqs	if (pa->value != cfg_value) {
10533dec9fcqs		pa->old_value = pa->value;
10543dec9fcqs		pa->value = cfg_value;
10553dec9fcqs		cfg_it = B_TRUE;
10563dec9fcqs	}
10573dec9fcqs
10583dec9fcqs	if (cfg_it == B_TRUE) {
10593dec9fcqs		status = hxge_pfc_set_hash(hxgep, (uint32_t)pa->value);
10603dec9fcqs		if (status != HXGE_OK)
10613dec9fcqs			return (EINVAL);
10623dec9fcqs	}
10633dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, " <== hxge_param_pfc_hash_init"));
10643dec9fcqs	return (0);
10653dec9fcqs}
10663dec9fcqs
10673dec9fcqs/* ARGSUSED */
10683dec9fcqsstatic int
10693dec9fcqshxge_param_set_hxge_debug_flag(p_hxge_t hxgep, queue_t *q,
10703dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
10713dec9fcqs{
10723dec9fcqs	char		*end;
10733dec9fcqs	uint32_t	status = 0;
10743dec9fcqs	uint64_t	cfg_value = 0;
10753dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
10763dec9fcqs	uint32_t	cfg_it = B_FALSE;
10773dec9fcqs
10783dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_hxge_debug_flag"));
1079a512c5dQiyan Sun - Sun Microsystems - San Diego United States
1080a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
1081a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
1082a512c5dQiyan Sun - Sun Microsystems - San Diego United States
10833dec9fcqs	cfg_value = mi_strtol(value, &end, BASE_HEX);
10843dec9fcqs
10853dec9fcqs	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
10863dec9fcqs		HXGE_DEBUG_MSG((hxgep, NDD_CTL,
10873dec9fcqs		    " hxge_param_set_hxge_debug_flag"
10883dec9fcqs		    " outof range %llx", cfg_value));
10893dec9fcqs		return (EINVAL);
10903dec9fcqs	}
10913dec9fcqs	if (pa->value != cfg_value) {
10923dec9fcqs		pa->old_value = pa->value;
10933dec9fcqs		pa->value = cfg_value;
10943dec9fcqs		cfg_it = B_TRUE;
10953dec9fcqs	}
10963dec9fcqs	if (cfg_it == B_TRUE)
10973dec9fcqs		hxgep->hxge_debug_level = pa->value;
10983dec9fcqs
10993dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_hxge_debug_flag"));
11003dec9fcqs	return (status);
11013dec9fcqs}
11023dec9fcqs
11033dec9fcqs/* ARGSUSED */
11043dec9fcqsstatic int
11053dec9fcqshxge_param_get_debug_flag(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
11063dec9fcqs{
11073dec9fcqs	int		status = 0;
11083dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
11093dec9fcqs
11103dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_get_debug_flag"));
11113dec9fcqs
11123dec9fcqs	if (pa->value > 0xffffffff)
11133dec9fcqs		(void) mi_mpprintf(mp, "%x%x", (int)(pa->value >> 32),
11143dec9fcqs		    (int)(pa->value & 0xffffffff));
11153dec9fcqs	else
11163dec9fcqs		(void) mi_mpprintf(mp, "%x", (int)pa->value);
11173dec9fcqs
11183dec9fcqs
11193dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_get_debug_flag"));
11203dec9fcqs	return (status);
11213dec9fcqs}
11223dec9fcqs
11233dec9fcqs/* ARGSUSED */
11243dec9fcqsstatic int
11253dec9fcqshxge_param_set_hpi_debug_flag(p_hxge_t hxgep, queue_t *q,
11263dec9fcqs	mblk_t *mp, char *value, caddr_t cp)
11273dec9fcqs{
11283dec9fcqs	char		*end;
11293dec9fcqs	uint32_t	status = 0;
11303dec9fcqs	uint64_t	cfg_value = 0;
11313dec9fcqs	p_hxge_param_t	pa = (p_hxge_param_t)cp;
11323dec9fcqs	uint32_t	cfg_it = B_FALSE;
11333dec9fcqs
11343dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "==> hxge_param_set_hpi_debug_flag"));
1135a512c5dQiyan Sun - Sun Microsystems - San Diego United States
1136a512c5dQiyan Sun - Sun Microsystems - San Diego United States	if (strncasecmp(value, "0x", 2) == 0)
1137a512c5dQiyan Sun - Sun Microsystems - San Diego United States		value += 2;
1138a512c5dQiyan Sun - Sun Microsystems - San Diego United States
11393dec9fcqs	cfg_value = mi_strtol(value, &end, BASE_HEX);
11403dec9fcqs
11413dec9fcqs	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
11423dec9fcqs		HXGE_DEBUG_MSG((hxgep, NDD_CTL, " hxge_param_set_hpi_debug_flag"
11433dec9fcqs		    " outof range %llx", cfg_value));
11443dec9fcqs		return (EINVAL);
11453dec9fcqs	}
11463dec9fcqs	if (pa->value != cfg_value) {
11473dec9fcqs		pa->old_value = pa->value;
11483dec9fcqs		pa->value = cfg_value;
11493dec9fcqs		cfg_it = B_TRUE;
11503dec9fcqs	}
11513dec9fcqs	if (cfg_it == B_TRUE) {
11523dec9fcqs		hpi_debug_level = pa->value;
11533dec9fcqs	}
11543dec9fcqs	HXGE_DEBUG_MSG((hxgep, NDD_CTL, "<== hxge_param_set_debug_flag"));
11553dec9fcqs	return (status);
11563dec9fcqs}
11573dec9fcqs
11583dec9fcqstypedef struct block_info {
11593dec9fcqs	char *name;
11603dec9fcqs	uint32_t offset;
11613dec9fcqs} block_info_t;
11623dec9fcqs
11633dec9fcqsblock_info_t reg_block[] = {
11643dec9fcqs	{"PIO", PIO_BASE_ADDR},
11653dec9fcqs	{"PIO_LDSV", PIO_LDSV_BASE_ADDR},
11663dec9fcqs	{"PIO_LDMASK", PIO_LDMASK_BASE_ADDR},
11673dec9fcqs	{"PFC", PFC_BASE_ADDR},
11683dec9fcqs	{"RDC", RDC_BASE_ADDR},
11693dec9fcqs	{"TDC", TDC_BASE_ADDR},
11703dec9fcqs	{"VMAC", VMAC_BASE_ADDR},
11713dec9fcqs	{"END", ALL_FF_32},
11723dec9fcqs};
11733dec9fcqs
11743dec9fcqs/* ARGSUSED */
11753dec9fcqsstatic int
11763dec9fcqshxge_param_dump_ptrs(p_hxge_t hxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
11773dec9fcqs{
11783dec9fcqs	uint_t			print_len, buf_len;
11793dec9fcqs	p_mblk_t		np;
11803dec9fcqs	int			rdc, tdc, block;
11813dec9fcqs	uint64_t		base;
11823dec9fcqs	p_hxge_dma_pt_cfg_t	p_dma_cfgp;
11833dec9fcqs	p_hxge_hw_pt_cfg_t	p_cfgp;
11843dec9fcqs	int			buff_alloc_size = HXGE_NDD_INFODUMP_BUFF_8K;
11853dec9fcqs	p_tx_ring_t		*tx_rings;
11863dec9fcqs	p_rx_rcr_rings_t	rx_rcr_rings;
11873dec9fcqs	p_rx_rcr_ring_t		*rcr_rings;
11883dec9fcqs	p_rx_rbr_rings_t	rx_rbr_rings;
11893dec9fcqs	p_rx_rbr_ring_t		*rbr_rings;
11903dec9fcqs
11913dec9fcqs	HXGE_DEBUG_MSG((hxgep, IOC_CTL, "==> hxge_param_dump_ptrs"));
11923dec9fcqs
11933dec9fcqs	(void) mi_mpprintf(mp, "ptr information\n");
11943dec9fcqs
11953dec9fcqs	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
11963dec9fcqs		/* The following may work even if we cannot get a large buf. */
11973dec9fcqs		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
11983dec9fcqs		return (0);
11993dec9fcqs	}
12003dec9fcqs	buf_len = buff_alloc_size;
12013dec9fcqs
12023dec9fcqs	mp->b_cont = np;
12033dec9fcqs	p_dma_cfgp = (p_hxge_dma_pt_cfg_t)&hxgep->pt_config;
12043dec9fcqs	p_cfgp = (p_hxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
12053dec9fcqs
12063dec9fcqs	rx_rcr_rings = hxgep->rx_rcr_rings;
12073dec9fcqs	rcr_rings = rx_rcr_rings->rcr_rings;
12083dec9fcqs	rx_rbr_rings = hxgep->rx_rbr_rings;
12093dec9fcqs	rbr_rings = rx_rbr_rings->rbr_rings;
12103dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12113dec9fcqs	    "hxgep (hxge_t) $%p\n dev_regs (dev_regs_t) $%p\n",
12121667122Michael Speer	    (void *)hxgep, (void *)hxgep->dev_regs);
12133dec9fcqs
12143dec9fcqs	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12153dec9fcqs	/* do register pointers */
12163dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12173dec9fcqs	    "reg base (hpi_reg_ptr_t) $%p\t pci reg (hpi_reg_ptr_t) $%p\n",
12181667122Michael Speer	    (void *)hxgep->dev_regs->hxge_regp,
12191667122Michael Speer	    (void *)hxgep->dev_regs->hxge_pciregp);
12203dec9fcqs
12213dec9fcqs	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12223dec9fcqs
12233dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12243dec9fcqs	    "\nBlock \t Offset \n");
12253dec9fcqs
12263dec9fcqs	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12273dec9fcqs	block = 0;
12283dec9fcqs#if defined(__i386)
12293dec9fcqs	base = (uint64_t)(uint32_t)hxgep->dev_regs->hxge_regp;
12303dec9fcqs#else
12313dec9fcqs	base = (uint64_t)hxgep->dev_regs->hxge_regp;
12323dec9fcqs#endif
12333dec9fcqs	while (reg_block[block].offset != ALL_FF_32) {
12343dec9fcqs		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12353dec9fcqs		    "%9s\t 0x%llx\n", reg_block[block].name,
12363dec9fcqs		    (unsigned long long) (reg_block[block].offset + base));
12373dec9fcqs		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12383dec9fcqs		block++;
12393dec9fcqs	}
12403dec9fcqs
12413dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12423dec9fcqs	    "\nRDC\t rcrp (rx_rcr_ring_t)\t rbrp (rx_rbr_ring_t)\n");
12433dec9fcqs
12443dec9fcqs	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12453dec9fcqs
12463dec9fcqs	for (rdc = 0; rdc < p_cfgp->max_rdcs; rdc++) {
12473dec9fcqs		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12483dec9fcqs		    " %d\t  $%p\t\t   $%p\n",
12491667122Michael Speer		    rdc, (void *)rcr_rings[rdc], (void *)rbr_rings[rdc]);
12503dec9fcqs		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12513dec9fcqs	}
12523dec9fcqs
12533dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12543dec9fcqs	    "\nTDC\t tdcp (tx_ring_t)\n");
12553dec9fcqs
12563dec9fcqs	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12573dec9fcqs	tx_rings = hxgep->tx_rings->rings;
12583dec9fcqs	for (tdc = 0; tdc < p_cfgp->max_tdcs; tdc++) {
12593dec9fcqs		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
12601667122Michael Speer		    " %d\t  $%p\n", tdc, (void *)tx_rings[tdc]);
12613dec9fcqs		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12623dec9fcqs	}
12633dec9fcqs
12643dec9fcqs	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, "\n\n");
12653dec9fcqs
12663dec9fcqs	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
12673dec9fcqs	HXGE_DEBUG_MSG((hxgep, IOC_CTL, "<== hxge_param_dump_ptrs"));
12683dec9fcqs	return (0);
12693dec9fcqs}
12703dec9fcqs
12713dec9fcqs/*
12723dec9fcqs * Load 'name' into the named dispatch table pointed to by 'ndp'.
12733dec9fcqs * 'ndp' should be the address of a char pointer cell.  If the table
12743dec9fcqs * does not exist (*ndp == 0), a new table is allocated and 'ndp'
12753dec9fcqs * is stuffed.  If there is not enough space in the table for a new
12763dec9fcqs * entry, more space is allocated.
12773dec9fcqs */
12783dec9fcqsboolean_t
12793dec9fcqshxge_nd_load(caddr_t *pparam, char *name,
12803dec9fcqs	pfi_t get_pfi, pfi_t set_pfi, caddr_t data)
12813dec9fcqs{
12823dec9fcqs	ND	*nd;
12833dec9fcqs	NDE	*nde;
12843dec9fcqs
12853dec9fcqs	HXGE_DEBUG_MSG((NULL, NDD2_CTL, " ==> hxge_nd_load: %s", name));
12863dec9fcqs	if (!pparam)
12873dec9fcqs		return (B_FALSE);
12883dec9fcqs	if ((nd = (ND *) * pparam) == NULL) {
12893dec9fcqs		if ((nd = (ND *) KMEM_ZALLOC(sizeof (ND), KM_NOSLEEP)) == NULL)
12903dec9fcqs			return (B_FALSE);
12913dec9fcqs		*pparam = (caddr_t)nd;
12923dec9fcqs	}
12933dec9fcqs	if (nd->nd_tbl) {
12943dec9fcqs		for (nde = nd->nd_tbl; nde->nde_name; nde++) {
12953dec9fcqs			if (strcmp(name, nde->nde_name) == 0)
12963dec9fcqs				goto fill_it;
12973dec9fcqs		}
12983dec9fcqs	}
12993dec9fcqs	if (nd->nd_free_count <= 1) {
13003dec9fcqs		if ((nde = (NDE *) KMEM_ZALLOC(nd->nd_size +
13013dec9fcqs		    NDE_ALLOC_SIZE, KM_NOSLEEP)) == NULL)
13023dec9fcqs			return (B_FALSE);
13033dec9fcqs		nd->nd_free_count += NDE_ALLOC_COUNT;
13043dec9fcqs		if (nd->nd_tbl) {
13053dec9fcqs			bcopy((char *)nd->nd_tbl, (char *)nde, nd->nd_size);
13063dec9fcqs			KMEM_FREE((char *)nd->nd_tbl, nd->nd_size);
13073dec9fcqs		} else {
13083dec9fcqs			nd->nd_free_count--;
13093dec9fcqs			nde->nde_name = "?";
13103dec9fcqs			nde->nde_get_pfi = hxge_nd_get_names;
13113dec9fcqs			nde->nde_set_pfi = hxge_set_default;
13123dec9fcqs		}
13133dec9fcqs		nde->nde_data = (caddr_t)nd;
13143dec9fcqs		nd->nd_tbl = nde;
13153dec9fcqs		nd->nd_size += NDE_ALLOC_SIZE;
13163dec9fcqs	}
13173dec9fcqs	for (nde = nd->nd_tbl; nde->nde_name; nde++)
13183dec9fcqs		noop;
13193dec9fcqs	nd->nd_free_count--;
13203dec9fcqsfill_it:
13213dec9fcqs	nde->nde_name = name;
13223dec9fcqs	nde->nde_get_pfi = get_pfi;
13233dec9fcqs	nde->nde_set_pfi = set_pfi;
13243dec9fcqs	nde->nde_data = data;
13253dec9fcqs	HXGE_DEBUG_MSG((NULL, NDD2_CTL, " <== hxge_nd_load"));
13263dec9fcqs
13273dec9fcqs	return (B_TRUE);
13283dec9fcqs}
13293dec9fcqs
13303dec9fcqs/*
13313dec9fcqs * Free the table pointed to by 'pparam'
13323dec9fcqs */
13333dec9fc