1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <sys/nxge/nxge_impl.h>
27#include <sys/nxge/nxge_hio.h>
28
29#include <inet/common.h>
30#include <inet/mi.h>
31#include <inet/nd.h>
32
33extern uint64_t npi_debug_level;
34
35#define	NXGE_PARAM_MAC_RW \
36	NXGE_PARAM_RW | NXGE_PARAM_MAC | \
37	NXGE_PARAM_NDD_WR_OK | NXGE_PARAM_READ_PROP
38
39#define	NXGE_PARAM_MAC_DONT_SHOW \
40	NXGE_PARAM_RW | NXGE_PARAM_MAC | NXGE_PARAM_DONT_SHOW
41
42#define	NXGE_PARAM_RXDMA_RW \
43	NXGE_PARAM_RWP | NXGE_PARAM_RXDMA | NXGE_PARAM_NDD_WR_OK | \
44	NXGE_PARAM_READ_PROP
45
46#define	NXGE_PARAM_RXDMA_RWC \
47	NXGE_PARAM_RWP | NXGE_PARAM_RXDMA | NXGE_PARAM_INIT_ONLY | \
48	NXGE_PARAM_READ_PROP
49
50#define	NXGE_PARAM_L2CLASS_CFG \
51	NXGE_PARAM_RW | NXGE_PARAM_PROP_ARR32 | NXGE_PARAM_READ_PROP | \
52	NXGE_PARAM_NDD_WR_OK
53
54#define	NXGE_PARAM_CLASS_RWS \
55	NXGE_PARAM_RWS |  NXGE_PARAM_READ_PROP
56
57#define	NXGE_PARAM_ARRAY_INIT_SIZE	0x20ULL
58
59#define	SET_RX_INTR_TIME_DISABLE 0
60#define	SET_RX_INTR_TIME_ENABLE 1
61#define	SET_RX_INTR_PKTS 2
62
63#define	BASE_ANY	0
64#define	BASE_BINARY 	2
65#define	BASE_HEX	16
66#define	BASE_DECIMAL	10
67#define	ALL_FF_64	0xFFFFFFFFFFFFFFFFULL
68#define	ALL_FF_32	0xFFFFFFFFUL
69
70#define	NXGE_NDD_INFODUMP_BUFF_SIZE	2048 /* is 2k enough? */
71#define	NXGE_NDD_INFODUMP_BUFF_8K	8192
72#define	NXGE_NDD_INFODUMP_BUFF_16K	0x2000
73#define	NXGE_NDD_INFODUMP_BUFF_64K	0x8000
74
75#define	PARAM_OUTOF_RANGE(vptr, eptr, rval, pa)	\
76	((vptr == eptr) || (rval < pa->minimum) || (rval > pa->maximum))
77
78#define	ADVANCE_PRINT_BUFFER(pmp, plen, rlen) { \
79	((mblk_t *)pmp)->b_wptr += plen; \
80	rlen -= plen; \
81}
82
83int nxge_param_set_mac(p_nxge_t, queue_t *,
84	mblk_t *, char *, caddr_t);
85static int nxge_param_set_port_rdc(p_nxge_t, queue_t *,
86	mblk_t *, char *, caddr_t);
87static int nxge_param_set_grp_rdc(p_nxge_t, queue_t *,
88	mblk_t *, char *, caddr_t);
89static int nxge_param_set_ether_usr(p_nxge_t,
90	queue_t *, mblk_t *, char *, caddr_t);
91static int nxge_param_set_ip_usr(p_nxge_t,
92	queue_t *, mblk_t *, char *, caddr_t);
93static int nxge_param_set_vlan_rdcgrp(p_nxge_t,
94	queue_t *, mblk_t *, char *, caddr_t);
95static int nxge_param_set_mac_rdcgrp(p_nxge_t,
96	queue_t *, mblk_t *, char *, caddr_t);
97static int nxge_param_fflp_hash_init(p_nxge_t,
98	queue_t *, mblk_t *, char *, caddr_t);
99static int nxge_param_llc_snap_enable(p_nxge_t, queue_t *,
100	mblk_t *, char *, caddr_t);
101static int nxge_param_hash_lookup_enable(p_nxge_t, queue_t *,
102	mblk_t *, char *, caddr_t);
103static int nxge_param_tcam_enable(p_nxge_t, queue_t *,
104	mblk_t *, char *, caddr_t);
105static int nxge_param_get_fw_ver(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
106static int nxge_param_get_port_mode(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
107static int nxge_param_get_rxdma_info(p_nxge_t, queue_t *q,
108	p_mblk_t, caddr_t);
109static int nxge_param_get_txdma_info(p_nxge_t, queue_t *q,
110	p_mblk_t, caddr_t);
111static int nxge_param_get_vlan_rdcgrp(p_nxge_t, queue_t *,
112	p_mblk_t, caddr_t);
113static int nxge_param_get_mac_rdcgrp(p_nxge_t, queue_t *,
114	p_mblk_t, caddr_t);
115static int nxge_param_get_rxdma_rdcgrp_info(p_nxge_t, queue_t *,
116	p_mblk_t, caddr_t);
117static int nxge_param_get_rx_intr_time(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
118static int nxge_param_get_rx_intr_pkts(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
119static int nxge_param_get_ip_opt(p_nxge_t, queue_t *, mblk_t *, caddr_t);
120static int nxge_param_get_mac(p_nxge_t, queue_t *q, p_mblk_t, caddr_t);
121static int nxge_param_get_debug_flag(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
122static int nxge_param_set_nxge_debug_flag(p_nxge_t, queue_t *, mblk_t *,
123	char *, caddr_t);
124static int nxge_param_set_npi_debug_flag(p_nxge_t,
125	queue_t *, mblk_t *, char *, caddr_t);
126static int nxge_param_dump_rdc(p_nxge_t, queue_t *q, p_mblk_t, caddr_t);
127static int nxge_param_dump_tdc(p_nxge_t, queue_t *q, p_mblk_t, caddr_t);
128static int nxge_param_dump_mac_regs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
129static int nxge_param_dump_ipp_regs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
130static int nxge_param_dump_fflp_regs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
131static int nxge_param_dump_vlan_table(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
132static int nxge_param_dump_rdc_table(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
133static int nxge_param_dump_ptrs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
134static void nxge_param_sync(p_nxge_t);
135
136/*
137 * Global array of Neptune changable parameters.
138 * This array is initialized to correspond to the default
139 * Neptune 4 port configuration. This array would be copied
140 * into each port's parameter structure and modifed per
141 * fcode and nxge.conf configuration. Later, the parameters are
142 * exported to ndd to display and run-time configuration (at least
143 * some of them).
144 *
145 * Parameters with DONT_SHOW are not shown by ndd.
146 *
147 */
148
149static nxge_param_t	nxge_param_arr[] = {
150	/*
151	 * min	max	value	old	hw-name	conf-name
152	 */
153	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
154		0, 999, 1000, 0, "instance", "instance"},
155
156	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
157		0, 999, 1000, 0, "main-instance", "main_instance"},
158
159	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ,
160		0, 3, 0, 0, "function-number", "function_number"},
161
162	/* Partition Id */
163	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
164		0, 8, 0, 0, "partition-id", "partition_id"},
165
166	/* Read Write Permission Mode */
167	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
168		0, 2, 0, 0, "read-write-mode", "read_write_mode"},
169
170	{ nxge_param_get_fw_ver, NULL, NXGE_PARAM_READ,
171		0, 32, 0, 0, "version",	"fw_version"},
172
173	{ nxge_param_get_port_mode, NULL, NXGE_PARAM_READ,
174		0, 32, 0, 0, "port-mode", "port_mode"},
175
176	/* hw cfg types */
177	/* control the DMA config of Neptune/NIU */
178	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
179		CFG_DEFAULT, CFG_CUSTOM, CFG_DEFAULT, CFG_DEFAULT,
180		"niu-cfg-type", "niu_cfg_type"},
181
182	/* control the TXDMA config of the Port controlled by tx-quick-cfg */
183	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
184		CFG_DEFAULT, CFG_CUSTOM, CFG_NOT_SPECIFIED, CFG_DEFAULT,
185		"tx-qcfg-type", "tx_qcfg_type"},
186
187	/* control the RXDMA config of the Port controlled by rx-quick-cfg */
188	{ nxge_param_get_generic, NULL, NXGE_PARAM_DONT_SHOW,
189		CFG_DEFAULT, CFG_CUSTOM, CFG_NOT_SPECIFIED, CFG_DEFAULT,
190		"rx-qcfg-type", "rx_qcfg_type"},
191
192	{ nxge_param_get_mac, nxge_param_set_mac,
193		NXGE_PARAM_RW  | NXGE_PARAM_DONT_SHOW,
194		0, 1, 0, 0, "master-cfg-enable", "master_cfg_enable"},
195
196	{ nxge_param_get_mac, nxge_param_set_mac,
197		NXGE_PARAM_DONT_SHOW,
198		0, 1, 0, 0, "master-cfg-value", "master_cfg_value"},
199
200	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_RW,
201		0, 1, 1, 1, "adv-autoneg-cap", "adv_autoneg_cap"},
202
203	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_RW,
204		0, 1, 1, 1, "adv-10gfdx-cap", "adv_10gfdx_cap"},
205
206	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_DONT_SHOW,
207		0, 1, 0, 0, "adv-10ghdx-cap", "adv_10ghdx_cap"},
208
209	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_RW,
210		0, 1, 1, 1, "adv-1000fdx-cap", "adv_1000fdx_cap"},
211
212	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_DONT_SHOW,
213		0, 1, 0, 0, "adv-1000hdx-cap",	"adv_1000hdx_cap"},
214
215	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_DONT_SHOW,
216		0, 1, 0, 0, "adv-100T4-cap", "adv_100T4_cap"},
217
218	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_RW,
219		0, 1, 1, 1, "adv-100fdx-cap", "adv_100fdx_cap"},
220
221	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_DONT_SHOW,
222		0, 1, 0, 0, "adv-100hdx-cap", "adv_100hdx_cap"},
223
224	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_RW,
225		0, 1, 1, 1, "adv-10fdx-cap", "adv_10fdx_cap"},
226
227	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_DONT_SHOW,
228		0, 1, 0, 0, "adv-10hdx-cap", "adv_10hdx_cap"},
229
230	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_DONT_SHOW,
231		0, 1, 0, 0, "adv-asmpause-cap",	"adv_asmpause_cap"},
232
233	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_MAC_RW,
234		0, 1, 0, 0, "adv-pause-cap", "adv_pause_cap"},
235
236	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_DONT_SHOW,
237		0, 1, 0, 0, "use-int-xcvr", "use_int_xcvr"},
238
239	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_DONT_SHOW,
240		0, 1, 1, 1, "enable-ipg0", "enable_ipg0"},
241
242	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_DONT_SHOW,
243		0, 255,	8, 8, "ipg0", "ipg0"},
244
245	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_DONT_SHOW,
246		0, 255,	8, 8, "ipg1", "ipg1"},
247
248	{ nxge_param_get_mac, nxge_param_set_mac, NXGE_PARAM_DONT_SHOW,
249		0, 255,	4, 4, "ipg2", "ipg2"},
250
251	/* Transmit DMA channels */
252	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ |
253		NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
254		0, 3, 0, 0, "tx-dma-weight", "tx_dma_weight"},
255
256	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ |
257		NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
258		0, 31, 0, 0, "tx-dma-channels-begin", "tx_dma_channels_begin"},
259
260	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ |
261		NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
262		0, 32, 0, 0, "tx-dma-channels", "tx_dma_channels"},
263	{ nxge_param_get_txdma_info, NULL,
264		NXGE_PARAM_READ | NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
265		0, 32, 0, 0, "tx-dma-info", "tx_dma_info"},
266
267	/* Receive DMA channels */
268	{ nxge_param_get_generic, NULL,
269		NXGE_PARAM_READ | NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
270		0, 31, 0, 0, "rx-dma-channels-begin", "rx_dma_channels_begin"},
271
272	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ |
273		NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
274		0, 32, 0, 0, "rx-dma-channels",	"rx_dma_channels"},
275
276	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ |
277		NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
278		0, 65535, PT_DRR_WT_DEFAULT_10G, 0,
279		"rx-drr-weight", "rx_drr_weight"},
280
281	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ |
282		NXGE_PARAM_READ_PROP | NXGE_PARAM_DONT_SHOW,
283		0, 1, 1, 0, "rx-full-header", "rx_full_header"},
284
285	{ nxge_param_get_rxdma_info, NULL, NXGE_PARAM_READ |
286		NXGE_PARAM_DONT_SHOW,
287		0, 32, 0, 0, "rx-dma-info", "rx_dma_info"},
288
289	{ nxge_param_get_rxdma_info, NULL,
290		NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
291		NXGE_RBR_RBB_MIN, NXGE_RBR_RBB_MAX, NXGE_RBR_RBB_DEFAULT, 0,
292		"rx-rbr-size", "rx_rbr_size"},
293
294	{ nxge_param_get_rxdma_info, NULL,
295		NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
296		NXGE_RCR_MIN, NXGE_RCR_MAX, NXGE_RCR_DEFAULT, 0,
297		"rx-rcr-size", "rx_rcr_size"},
298
299	{ nxge_param_get_generic, nxge_param_set_port_rdc,
300		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
301		0, 15, 0, 0, "default-port-rdc", "default_port_rdc"},
302
303	{ nxge_param_get_rx_intr_time, nxge_param_rx_intr_time,
304		NXGE_PARAM_RXDMA_RW,
305		NXGE_RDC_RCR_TIMEOUT_MIN, NXGE_RDC_RCR_TIMEOUT_MAX,
306		NXGE_RDC_RCR_TIMEOUT, 0, "rxdma-intr-time", "rxdma_intr_time"},
307
308	{ nxge_param_get_rx_intr_pkts, nxge_param_rx_intr_pkts,
309		NXGE_PARAM_RXDMA_RW,
310		NXGE_RDC_RCR_THRESHOLD_MIN, NXGE_RDC_RCR_THRESHOLD_MAX,
311		NXGE_RDC_RCR_THRESHOLD, 0,
312		"rxdma-intr-pkts", "rxdma_intr_pkts"},
313
314	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ_PROP |
315		NXGE_PARAM_DONT_SHOW,
316		0, 8, 0, 0, "rx-rdc-grps-begin", "rx_rdc_grps_begin"},
317
318	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ_PROP |
319		NXGE_PARAM_DONT_SHOW,
320		0, 8, 0, 0, "rx-rdc-grps", "rx_rdc_grps"},
321
322	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
323		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
324		0, 15, 0, 0, "default-grp0-rdc", "default_grp0_rdc"},
325
326	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
327		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
328		0, 15,	2, 0, "default-grp1-rdc", "default_grp1_rdc"},
329
330	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
331		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
332		0, 15, 4, 0, "default-grp2-rdc", "default_grp2_rdc"},
333
334	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
335		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
336		0, 15, 6, 0, "default-grp3-rdc", "default_grp3_rdc"},
337
338	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
339		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
340		0, 15, 8, 0, "default-grp4-rdc", "default_grp4_rdc"},
341
342	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
343		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
344		0, 15, 10, 0, "default-grp5-rdc", "default_grp5_rdc"},
345
346	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
347		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
348		0, 15, 12, 0, "default-grp6-rdc", "default_grp6_rdc"},
349
350	{ nxge_param_get_generic, nxge_param_set_grp_rdc,
351		NXGE_PARAM_RXDMA_RW | NXGE_PARAM_DONT_SHOW,
352		0, 15, 14, 0, "default-grp7-rdc", "default_grp7_rdc"},
353
354	{ nxge_param_get_rxdma_rdcgrp_info, NULL,
355		NXGE_PARAM_READ | NXGE_PARAM_CMPLX | NXGE_PARAM_DONT_SHOW,
356		0, 8, 0, 0, "rdc-groups-info", "rdc_groups_info"},
357
358	/* Logical device groups */
359	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
360		0, 63, 0, 0, "start-ldg", "start_ldg"},
361
362	{ nxge_param_get_generic, NULL, NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
363		0, 64, 0, 0, "max-ldg", "max_ldg" },
364
365	/* MAC table information */
366	{ nxge_param_get_mac_rdcgrp, nxge_param_set_mac_rdcgrp,
367		NXGE_PARAM_L2CLASS_CFG | NXGE_PARAM_DONT_SHOW,
368		0, 31, 0, 0, "mac-2rdc-grp", "mac_2rdc_grp"},
369
370	/* VLAN table information */
371	{ nxge_param_get_vlan_rdcgrp, nxge_param_set_vlan_rdcgrp,
372		NXGE_PARAM_L2CLASS_CFG | NXGE_PARAM_DONT_SHOW,
373		0, 31, 0, 0, "vlan-2rdc-grp", "vlan_2rdc_grp"},
374
375	{ nxge_param_get_generic, NULL,
376		NXGE_PARAM_READ_PROP | NXGE_PARAM_READ |
377		NXGE_PARAM_PROP_ARR32 | NXGE_PARAM_DONT_SHOW,
378		0, 0x0ffff, 0x0ffff, 0, "fcram-part-cfg", "fcram_part_cfg"},
379
380	{ nxge_param_get_generic, NULL, NXGE_PARAM_CLASS_RWS |
381		NXGE_PARAM_DONT_SHOW,
382		0, 0x10, 0xa, 0, "fcram-access-ratio", "fcram_access_ratio"},
383
384	{ nxge_param_get_generic, NULL, NXGE_PARAM_CLASS_RWS |
385		NXGE_PARAM_DONT_SHOW,
386		0, 0x10, 0xa, 0, "tcam-access-ratio", "tcam_access_ratio"},
387
388	{ nxge_param_get_generic, nxge_param_tcam_enable,
389		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
390		0, 0x1, 0x0, 0, "tcam-enable", "tcam_enable"},
391
392	{ nxge_param_get_generic, nxge_param_hash_lookup_enable,
393		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
394		0, 0x01, 0x0, 0, "hash-lookup-enable", "hash_lookup_enable"},
395
396	{ nxge_param_get_generic, nxge_param_llc_snap_enable,
397		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
398		0, 0x01, 0x01, 0, "llc-snap-enable", "llc_snap_enable"},
399
400	{ nxge_param_get_generic, nxge_param_fflp_hash_init,
401		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
402		0, ALL_FF_32, ALL_FF_32, 0, "h1-init-value", "h1_init_value"},
403
404	{ nxge_param_get_generic,	nxge_param_fflp_hash_init,
405		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
406		0, 0x0ffff, 0x0ffff, 0, "h2-init-value", "h2_init_value"},
407
408	{ nxge_param_get_generic, nxge_param_set_ether_usr,
409		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
410		0, ALL_FF_32, 0x0, 0,
411		"class-cfg-ether-usr1", "class_cfg_ether_usr1"},
412
413	{ nxge_param_get_generic, nxge_param_set_ether_usr,
414		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
415		0, ALL_FF_32, 0x0, 0,
416		"class-cfg-ether-usr2", "class_cfg_ether_usr2"},
417
418	{ nxge_param_get_generic, nxge_param_set_ip_usr,
419		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
420		0, ALL_FF_32, 0x0, 0,
421		"class-cfg-ip-usr4", "class_cfg_ip_usr4"},
422
423	{ nxge_param_get_generic, nxge_param_set_ip_usr,
424		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
425		0, ALL_FF_32, 0x0, 0,
426		"class-cfg-ip-usr5", "class_cfg_ip_usr5"},
427
428	{ nxge_param_get_generic, nxge_param_set_ip_usr,
429		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
430		0, ALL_FF_32, 0x0, 0,
431		"class-cfg-ip-usr6", "class_cfg_ip_usr6"},
432
433	{ nxge_param_get_generic, nxge_param_set_ip_usr,
434		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
435		0, ALL_FF_32, 0x0, 0,
436		"class-cfg-ip-usr7", "class_cfg_ip_usr7"},
437
438	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
439		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
440		0, ALL_FF_32, 0x0, 0,
441		"class-opt-ip-usr4", "class_opt_ip_usr4"},
442
443	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
444		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
445		0, ALL_FF_32, 0x0, 0,
446		"class-opt-ip-usr5", "class_opt_ip_usr5"},
447
448	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
449		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
450		0, ALL_FF_32, 0x0, 0,
451		"class-opt-ip-usr6", "class_opt_ip_usr6"},
452
453	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
454		NXGE_PARAM_CLASS_RWS | NXGE_PARAM_DONT_SHOW,
455		0, ALL_FF_32, 0x0, 0,
456		"class-opt-ip-usr7", "class_opt_ip_usr7"},
457
458	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
459		NXGE_PARAM_CLASS_RWS,
460		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
461		"class-opt-ipv4-tcp", "class_opt_ipv4_tcp"},
462
463	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
464		NXGE_PARAM_CLASS_RWS,
465		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
466		"class-opt-ipv4-udp", "class_opt_ipv4_udp"},
467
468	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
469		NXGE_PARAM_CLASS_RWS,
470		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
471		"class-opt-ipv4-ah", "class_opt_ipv4_ah"},
472
473	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt,
474		NXGE_PARAM_CLASS_RWS,
475		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
476		"class-opt-ipv4-sctp", "class_opt_ipv4_sctp"},
477
478	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt, NXGE_PARAM_CLASS_RWS,
479		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
480		"class-opt-ipv6-tcp", "class_opt_ipv6_tcp"},
481
482	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt, NXGE_PARAM_CLASS_RWS,
483		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
484		"class-opt-ipv6-udp", "class_opt_ipv6_udp"},
485
486	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt, NXGE_PARAM_CLASS_RWS,
487		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
488		"class-opt-ipv6-ah", "class_opt_ipv6_ah"},
489
490	{ nxge_param_get_ip_opt, nxge_param_set_ip_opt, NXGE_PARAM_CLASS_RWS,
491		0, ALL_FF_32, NXGE_CLASS_FLOW_GEN_SERVER, 0,
492		"class-opt-ipv6-sctp",	"class_opt_ipv6_sctp"},
493
494	{ nxge_param_get_debug_flag, nxge_param_set_nxge_debug_flag,
495		NXGE_PARAM_RW | NXGE_PARAM_DONT_SHOW,
496		0ULL, ALL_FF_64, 0ULL, 0ULL,
497		"nxge-debug-flag", "nxge_debug_flag"},
498
499	{ nxge_param_get_debug_flag, nxge_param_set_npi_debug_flag,
500		NXGE_PARAM_RW | NXGE_PARAM_DONT_SHOW,
501		0ULL, ALL_FF_64, 0ULL, 0ULL,
502		"npi-debug-flag", "npi_debug_flag"},
503
504	{ nxge_param_dump_tdc, NULL, NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
505		0, 0x0fffffff, 0x0fffffff, 0, "dump-tdc", "dump_tdc"},
506
507	{ nxge_param_dump_rdc, NULL, NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
508		0, 0x0fffffff, 0x0fffffff, 0, "dump-rdc", "dump_rdc"},
509
510	{ nxge_param_dump_mac_regs, NULL, NXGE_PARAM_READ |
511		NXGE_PARAM_DONT_SHOW,
512		0, 0x0fffffff, 0x0fffffff, 0, "dump-mac-regs", "dump_mac_regs"},
513
514	{ nxge_param_dump_ipp_regs, NULL, NXGE_PARAM_READ |
515		NXGE_PARAM_DONT_SHOW,
516		0, 0x0fffffff, 0x0fffffff, 0, "dump-ipp-regs", "dump_ipp_regs"},
517
518	{ nxge_param_dump_fflp_regs, NULL, NXGE_PARAM_READ |
519		NXGE_PARAM_DONT_SHOW,
520		0, 0x0fffffff, 0x0fffffff, 0,
521		"dump-fflp-regs", "dump_fflp_regs"},
522
523	{ nxge_param_dump_vlan_table, NULL, NXGE_PARAM_READ |
524		NXGE_PARAM_DONT_SHOW,
525		0, 0x0fffffff, 0x0fffffff, 0,
526		"dump-vlan-table", "dump_vlan_table"},
527
528	{ nxge_param_dump_rdc_table, NULL, NXGE_PARAM_READ |
529		NXGE_PARAM_DONT_SHOW,
530		0, 0x0fffffff, 0x0fffffff, 0,
531		"dump-rdc-table", "dump_rdc_table"},
532
533	{ nxge_param_dump_ptrs,	NULL, NXGE_PARAM_READ |
534		NXGE_PARAM_DONT_SHOW,
535		0, 0x0fffffff, 0x0fffffff, 0, "dump-ptrs", "dump_ptrs"},
536
537	{  NULL, NULL, NXGE_PARAM_READ | NXGE_PARAM_DONT_SHOW,
538		0, 0x0fffffff, 0x0fffffff, 0, "end", "end"},
539};
540
541extern void 		*nxge_list;
542
543void
544nxge_get_param_soft_properties(p_nxge_t nxgep)
545{
546
547	p_nxge_param_t 		param_arr;
548	uint_t 			prop_len;
549	int 			i, j;
550	uint32_t		param_count;
551	uint32_t		*int_prop_val;
552
553	NXGE_DEBUG_MSG((nxgep, DDI_CTL, " ==> nxge_get_param_soft_properties"));
554
555	param_arr = nxgep->param_arr;
556	param_count = nxgep->param_count;
557	for (i = 0; i < param_count; i++) {
558		if ((param_arr[i].type & NXGE_PARAM_READ_PROP) == 0)
559			continue;
560		if ((param_arr[i].type & NXGE_PARAM_PROP_STR))
561			continue;
562		if ((param_arr[i].type & NXGE_PARAM_PROP_ARR32) ||
563		    (param_arr[i].type & NXGE_PARAM_PROP_ARR64)) {
564			if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
565			    nxgep->dip, 0, param_arr[i].fcode_name,
566			    (int **)&int_prop_val,
567			    (uint_t *)&prop_len)
568			    == DDI_PROP_SUCCESS) {
569				uint32_t *cfg_value;
570				uint64_t prop_count;
571
572				if (prop_len > NXGE_PARAM_ARRAY_INIT_SIZE)
573					prop_len = NXGE_PARAM_ARRAY_INIT_SIZE;
574#if defined(__i386)
575				cfg_value =
576				    (uint32_t *)(int32_t)param_arr[i].value;
577#else
578				cfg_value = (uint32_t *)param_arr[i].value;
579#endif
580				for (j = 0; j < prop_len; j++) {
581					cfg_value[j] = int_prop_val[j];
582				}
583				prop_count = prop_len;
584				param_arr[i].type |=
585				    (prop_count << NXGE_PARAM_ARRAY_CNT_SHIFT);
586				ddi_prop_free(int_prop_val);
587			}
588			continue;
589		}
590
591		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
592		    param_arr[i].fcode_name,
593		    (int **)&int_prop_val,
594		    &prop_len) == DDI_PROP_SUCCESS) {
595			if ((*int_prop_val >= param_arr[i].minimum) &&
596			    (*int_prop_val <= param_arr[i].maximum))
597				param_arr[i].value = *int_prop_val;
598#ifdef NXGE_DEBUG_ERROR
599			else {
600				NXGE_DEBUG_MSG((nxgep, OBP_CTL,
601				    "nxge%d: 'prom' file parameter error\n",
602				    nxgep->instance));
603				NXGE_DEBUG_MSG((nxgep, OBP_CTL,
604				    "Parameter keyword '%s'"
605				    " is outside valid range\n",
606				    param_arr[i].name));
607			}
608#endif
609			ddi_prop_free(int_prop_val);
610		}
611
612		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxgep->dip, 0,
613		    param_arr[i].name,
614		    (int **)&int_prop_val,
615		    &prop_len) == DDI_PROP_SUCCESS) {
616			if ((*int_prop_val >= param_arr[i].minimum) &&
617			    (*int_prop_val <= param_arr[i].maximum))
618				param_arr[i].value = *int_prop_val;
619#ifdef NXGE_DEBUG_ERROR
620			else {
621				NXGE_DEBUG_MSG((nxgep, OBP_CTL,
622				    "nxge%d: 'conf' file parameter error\n",
623				    nxgep->instance));
624				NXGE_DEBUG_MSG((nxgep, OBP_CTL,
625				    "Parameter keyword '%s'"
626				    "is outside valid range\n",
627				    param_arr[i].name));
628			}
629#endif
630			ddi_prop_free(int_prop_val);
631		}
632	}
633}
634
635static int
636nxge_private_param_register(p_nxge_t nxgep, p_nxge_param_t param_arr)
637{
638	int status = B_TRUE;
639	int channel;
640	uint8_t grp;
641	char *prop_name;
642	char *end;
643	uint32_t name_chars;
644
645	NXGE_DEBUG_MSG((nxgep, NDD2_CTL,
646	    "nxge_private_param_register %s", param_arr->name));
647
648	if ((param_arr->type & NXGE_PARAM_PRIV) != NXGE_PARAM_PRIV)
649		return (B_TRUE);
650
651	prop_name =  param_arr->name;
652	if (param_arr->type & NXGE_PARAM_RXDMA) {
653		if (strncmp("rxdma_intr", prop_name, 10) == 0)
654			return (B_TRUE);
655		name_chars = strlen("default_grp");
656		if (strncmp("default_grp", prop_name, name_chars) == 0) {
657			prop_name += name_chars;
658			grp = mi_strtol(prop_name, &end, 10);
659				/* now check if this rdcgrp is in config */
660			return (nxge_check_rdcgrp_port_member(nxgep, grp));
661		}
662		name_chars = strlen(prop_name);
663		if (strncmp("default_port_rdc", prop_name, name_chars) == 0) {
664			return (B_TRUE);
665		}
666		return (B_FALSE);
667	}
668
669	if (param_arr->type & NXGE_PARAM_TXDMA) {
670		name_chars = strlen("txdma");
671		if (strncmp("txdma", prop_name, name_chars) == 0) {
672			prop_name += name_chars;
673			channel = mi_strtol(prop_name, &end, 10);
674				/* now check if this rdc is in config */
675			NXGE_DEBUG_MSG((nxgep, NDD2_CTL,
676			    " nxge_private_param_register: %d",
677			    channel));
678			return (nxge_check_txdma_port_member(nxgep, channel));
679		}
680		return (B_FALSE);
681	}
682
683	status = B_FALSE;
684	NXGE_DEBUG_MSG((nxgep, NDD2_CTL, "<== nxge_private_param_register"));
685
686	return (status);
687}
688
689void
690nxge_setup_param(p_nxge_t nxgep)
691{
692	p_nxge_param_t param_arr;
693	int i;
694	pfi_t set_pfi;
695
696	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_setup_param"));
697
698	/*
699	 * Make sure the param_instance is set to a valid device instance.
700	 */
701	if (nxge_param_arr[param_instance].value == 1000)
702		nxge_param_arr[param_instance].value = nxgep->instance;
703
704	param_arr = nxgep->param_arr;
705	param_arr[param_instance].value = nxgep->instance;
706	param_arr[param_function_number].value = nxgep->function_num;
707
708	for (i = 0; i < nxgep->param_count; i++) {
709		if ((param_arr[i].type & NXGE_PARAM_PRIV) &&
710		    (nxge_private_param_register(nxgep,
711		    &param_arr[i]) == B_FALSE)) {
712			param_arr[i].setf = NULL;
713			param_arr[i].getf = NULL;
714		}
715
716		if (param_arr[i].type & NXGE_PARAM_CMPLX)
717			param_arr[i].setf = NULL;
718
719		if (param_arr[i].type & NXGE_PARAM_DONT_SHOW) {
720			param_arr[i].setf = NULL;
721			param_arr[i].getf = NULL;
722		}
723
724		set_pfi = (pfi_t)param_arr[i].setf;
725
726		if ((set_pfi) && (param_arr[i].type & NXGE_PARAM_INIT_ONLY)) {
727			set_pfi = NULL;
728		}
729
730	}
731	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_setup_param"));
732}
733
734void
735nxge_init_param(p_nxge_t nxgep)
736{
737	p_nxge_param_t param_arr;
738	int i, alloc_size;
739	uint64_t alloc_count;
740	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_init_param"));
741	/*
742	 * Make sure the param_instance is set to a valid device instance.
743	 */
744	if (nxge_param_arr[param_instance].value == 1000)
745		nxge_param_arr[param_instance].value = nxgep->instance;
746
747	param_arr = nxgep->param_arr;
748	if (param_arr == NULL) {
749		param_arr = (p_nxge_param_t)
750		    KMEM_ZALLOC(sizeof (nxge_param_arr), KM_SLEEP);
751	}
752
753	for (i = 0; i < sizeof (nxge_param_arr)/sizeof (nxge_param_t); i++) {
754		param_arr[i] = nxge_param_arr[i];
755		if ((param_arr[i].type & NXGE_PARAM_PROP_ARR32) ||
756		    (param_arr[i].type & NXGE_PARAM_PROP_ARR64)) {
757			alloc_count = NXGE_PARAM_ARRAY_INIT_SIZE;
758			alloc_size = alloc_count * sizeof (uint64_t);
759			param_arr[i].value =
760#if defined(__i386)
761			    (uint64_t)(uint32_t)KMEM_ZALLOC(alloc_size,
762			    KM_SLEEP);
763#else
764			(uint64_t)KMEM_ZALLOC(alloc_size, KM_SLEEP);
765#endif
766			param_arr[i].old_value =
767#if defined(__i386)
768			    (uint64_t)(uint32_t)KMEM_ZALLOC(alloc_size,
769			    KM_SLEEP);
770#else
771			(uint64_t)KMEM_ZALLOC(alloc_size, KM_SLEEP);
772#endif
773			param_arr[i].type |=
774			    (alloc_count << NXGE_PARAM_ARRAY_ALLOC_SHIFT);
775		}
776	}
777
778	nxgep->param_arr = param_arr;
779	nxgep->param_count = sizeof (nxge_param_arr)/sizeof (nxge_param_t);
780
781	nxge_param_sync(nxgep);
782
783	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_init_param: count %d",
784	    nxgep->param_count));
785}
786
787void
788nxge_destroy_param(p_nxge_t nxgep)
789{
790	int i;
791	uint64_t free_size, free_count;
792
793	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "==> nxge_destroy_param"));
794
795	if (nxgep->param_arr == NULL)
796		return;
797	/*
798	 * Make sure the param_instance is set to a valid device instance.
799	 */
800	if (nxge_param_arr[param_instance].value == nxgep->instance) {
801		for (i = 0; i <= nxge_param_arr[param_instance].maximum; i++) {
802			if ((ddi_get_soft_state(nxge_list, i) != NULL) &&
803			    (i != nxgep->instance))
804				break;
805		}
806		nxge_param_arr[param_instance].value = i;
807	}
808
809	for (i = 0; i < nxgep->param_count; i++)
810		if ((nxgep->param_arr[i].type & NXGE_PARAM_PROP_ARR32) ||
811		    (nxgep->param_arr[i].type & NXGE_PARAM_PROP_ARR64)) {
812			free_count = ((nxgep->param_arr[i].type &
813			    NXGE_PARAM_ARRAY_ALLOC_MASK) >>
814			    NXGE_PARAM_ARRAY_ALLOC_SHIFT);
815			free_count = NXGE_PARAM_ARRAY_INIT_SIZE;
816			free_size = sizeof (uint64_t) * free_count;
817#if defined(__i386)
818			KMEM_FREE((void *)(uint32_t)nxgep->param_arr[i].value,
819			    free_size);
820#else
821			KMEM_FREE((void *)nxgep->param_arr[i].value, free_size);
822#endif
823#if defined(__i386)
824			KMEM_FREE((void *)(uint32_t)
825			    nxgep->param_arr[i].old_value, free_size);
826#else
827			KMEM_FREE((void *)nxgep->param_arr[i].old_value,
828			    free_size);
829#endif
830		}
831
832	KMEM_FREE(nxgep->param_arr, sizeof (nxge_param_arr));
833	NXGE_DEBUG_MSG((nxgep, DDI_CTL, "<== nxge_destroy_param"));
834}
835
836/*
837 * Extracts the value from the 'nxge' parameter array and prints the
838 * parameter value. cp points to the required parameter.
839 */
840
841/* ARGSUSED */
842int
843nxge_param_get_generic(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
844{
845	p_nxge_param_t pa = (p_nxge_param_t)cp;
846
847	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
848	    "==> nxge_param_get_generic name %s ", pa->name));
849
850	if (pa->value > 0xffffffff)
851		(void) mi_mpprintf(mp, "%x%x",
852		    (int)(pa->value >> 32), (int)(pa->value & 0xffffffff));
853	else
854		(void) mi_mpprintf(mp, "%x", (int)pa->value);
855
856	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_generic"));
857	return (0);
858}
859
860/* ARGSUSED */
861static int
862nxge_param_get_mac(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
863{
864	p_nxge_param_t pa = (p_nxge_param_t)cp;
865
866	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_mac"));
867
868	(void) mi_mpprintf(mp, "%d", (uint32_t)pa->value);
869	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_mac"));
870	return (0);
871}
872
873/* ARGSUSED */
874static int
875nxge_param_get_fw_ver(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
876{
877	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_fw_ver"));
878
879	(void) mi_mpprintf(mp, "Firmware version for nxge%d:  %s\n",
880	    nxgep->instance, nxgep->vpd_info.ver);
881
882	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_fw_ver"));
883	return (0);
884}
885
886/* ARGSUSED */
887static int
888nxge_param_get_port_mode(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
889{
890	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_port_mode"));
891
892	switch (nxgep->mac.portmode) {
893	case PORT_1G_COPPER:
894		(void) mi_mpprintf(mp, "Port mode for nxge%d:  1G Copper %s\n",
895		    nxgep->instance,
896		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
897		break;
898	case PORT_1G_FIBER:
899		(void) mi_mpprintf(mp, "Port mode for nxge%d:  1G Fiber %s\n",
900		    nxgep->instance,
901		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
902		break;
903	case PORT_10G_COPPER:
904		(void) mi_mpprintf(mp, "Port mode for nxge%d:  10G Copper "
905		    "%s\n", nxgep->instance,
906		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
907		break;
908	case PORT_10G_FIBER:
909		(void) mi_mpprintf(mp, "Port mode for nxge%d:  10G Fiber %s\n",
910		    nxgep->instance,
911		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
912		break;
913	case PORT_10G_SERDES:
914		(void) mi_mpprintf(mp, "Port mode for nxge%d:  10G Serdes "
915		    "%s\n", nxgep->instance,
916		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
917		break;
918	case PORT_1G_SERDES:
919		(void) mi_mpprintf(mp, "Port mode for nxge%d:  1G Serdes %s\n",
920		    nxgep->instance,
921		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
922		break;
923	case PORT_1G_RGMII_FIBER:
924		(void) mi_mpprintf(mp, "Port mode for nxge%d:  1G RGMII "
925		    "Fiber %s\n", nxgep->instance,
926		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
927		break;
928	case PORT_HSP_MODE:
929		(void) mi_mpprintf(mp, "Port mode for nxge%d:  Hot Swappable "
930		    "PHY, Currently NOT present\n", nxgep->instance);
931		break;
932	case PORT_10G_TN1010:
933		(void) mi_mpprintf(mp, "Port mode for nxge%d:"
934		    " 10G Copper with TN1010 %s\n", nxgep->instance,
935		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
936		break;
937	case PORT_1G_TN1010:
938		(void) mi_mpprintf(mp, "Port mode for nxge%d:"
939		    " 1G Copper with TN1010 %s\n", nxgep->instance,
940		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
941		break;
942	default:
943		(void) mi_mpprintf(mp, "Port mode for nxge%d:  Unknown %s\n",
944		    nxgep->instance,
945		    nxgep->hot_swappable_phy ? "[Hot Swappable]" : "");
946		break;
947	}
948
949	(void) mi_mpprintf(mp, "Software LSO for nxge%d: %s\n",
950	    nxgep->instance,
951	    nxgep->soft_lso_enable ? "enable" : "disable");
952
953	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_port_mode"));
954	return (0);
955}
956
957/* ARGSUSED */
958static int
959nxge_param_get_rx_intr_time(p_nxge_t nxgep, queue_t *q, mblk_t *mp, caddr_t cp)
960{
961	p_nxge_param_t pa = (p_nxge_param_t)cp;
962
963	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_rx_intr_time"));
964
965	pa->value = (uint32_t)nxgep->intr_timeout;
966	(void) mi_mpprintf(mp, "%d", (uint32_t)nxgep->intr_timeout);
967
968	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_rx_intr_time"));
969	return (0);
970}
971
972/* ARGSUSED */
973static int
974nxge_param_get_rx_intr_pkts(p_nxge_t nxgep, queue_t *q, mblk_t *mp, caddr_t cp)
975{
976	p_nxge_param_t pa = (p_nxge_param_t)cp;
977
978	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_rx_intr_pkts"));
979
980	pa->value = (uint32_t)nxgep->intr_threshold;
981	(void) mi_mpprintf(mp, "%d", (uint32_t)nxgep->intr_threshold);
982
983	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_rx_intr_pkts"));
984	return (0);
985}
986
987/* ARGSUSED */
988int
989nxge_param_get_txdma_info(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
990{
991
992	uint_t print_len, buf_len;
993	p_mblk_t np;
994
995	int buff_alloc_size = NXGE_NDD_INFODUMP_BUFF_SIZE;
996	int tdc;
997
998	nxge_grp_set_t *set;
999
1000	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_txdma_info"));
1001
1002	(void) mi_mpprintf(mp, "TXDMA Information for Port\t %d \n",
1003	    nxgep->function_num);
1004
1005	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
1006		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
1007		return (0);
1008	}
1009
1010	buf_len = buff_alloc_size;
1011	mp->b_cont = np;
1012	print_len = 0;
1013
1014	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
1015	    "TDC\t HW TDC\t\n");
1016	((mblk_t *)np)->b_wptr += print_len;
1017	buf_len -= print_len;
1018
1019	set = &nxgep->tx_set;
1020	for (tdc = 0; tdc < NXGE_MAX_TDCS; tdc++) {
1021		if ((1 << tdc) & set->owned.map) {
1022			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1023			    buf_len, "%d\n", tdc);
1024			((mblk_t *)np)->b_wptr += print_len;
1025			buf_len -= print_len;
1026		}
1027	}
1028
1029	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_txdma_info"));
1030	return (0);
1031}
1032
1033/* ARGSUSED */
1034int
1035nxge_param_get_rxdma_info(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
1036{
1037	uint_t			print_len, buf_len;
1038	p_mblk_t		np;
1039	int			rdc;
1040	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1041	p_nxge_hw_pt_cfg_t	p_cfgp;
1042	int			buff_alloc_size = NXGE_NDD_INFODUMP_BUFF_SIZE;
1043	p_rx_rcr_rings_t 	rx_rcr_rings;
1044	p_rx_rcr_ring_t		*rcr_rings;
1045	p_rx_rbr_rings_t 	rx_rbr_rings;
1046	p_rx_rbr_ring_t		*rbr_rings;
1047	nxge_grp_set_t		*set;
1048
1049	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_rxdma_info"));
1050
1051	(void) mi_mpprintf(mp, "RXDMA Information for Port\t %d \n",
1052	    nxgep->function_num);
1053
1054	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
1055		/* The following may work even if we cannot get a large buf. */
1056		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
1057		return (0);
1058	}
1059
1060	buf_len = buff_alloc_size;
1061	mp->b_cont = np;
1062	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1063	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1064
1065	rx_rcr_rings = nxgep->rx_rcr_rings;
1066	rcr_rings = rx_rcr_rings->rcr_rings;
1067	rx_rbr_rings = nxgep->rx_rbr_rings;
1068	rbr_rings = rx_rbr_rings->rbr_rings;
1069
1070	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
1071	    "Total RDCs\t %d\n", p_cfgp->max_rdcs);
1072
1073	((mblk_t *)np)->b_wptr += print_len;
1074	buf_len -= print_len;
1075	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
1076	    "RDC\t HW RDC\t Timeout\t Packets RBR ptr \t"
1077	    "chunks\t RCR ptr\n");
1078
1079	((mblk_t *)np)->b_wptr += print_len;
1080	buf_len -= print_len;
1081
1082	set = &nxgep->rx_set;
1083	for (rdc = 0; rdc < NXGE_MAX_RDCS; rdc++) {
1084		if ((1 << rdc) & set->owned.map) {
1085			print_len = snprintf((char *)
1086			    ((mblk_t *)np)->b_wptr, buf_len,
1087			    " %d\t   %x\t\t %x\t $%p\t 0x%x\t $%p\n",
1088			    rdc,
1089			    p_dma_cfgp->rcr_timeout[rdc],
1090			    p_dma_cfgp->rcr_threshold[rdc],
1091			    (void *)rbr_rings[rdc],
1092			    rbr_rings[rdc]->num_blocks, (void *)rcr_rings[rdc]);
1093			((mblk_t *)np)->b_wptr += print_len;
1094			buf_len -= print_len;
1095		}
1096	}
1097
1098	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_rxdma_info"));
1099	return (0);
1100}
1101
1102/* ARGSUSED */
1103int
1104nxge_param_get_rxdma_rdcgrp_info(p_nxge_t nxgep, queue_t *q,
1105    p_mblk_t mp, caddr_t cp)
1106{
1107	uint_t			print_len, buf_len;
1108	p_mblk_t		np;
1109	int			offset, rdc, i, rdc_grp;
1110	p_nxge_rdc_grp_t	rdc_grp_p;
1111	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1112	p_nxge_hw_pt_cfg_t	p_cfgp;
1113
1114	int buff_alloc_size = NXGE_NDD_INFODUMP_BUFF_SIZE;
1115	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1116	    "==> nxge_param_get_rxdma_rdcgrp_info"));
1117
1118	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1119	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1120
1121	(void) mi_mpprintf(mp, "RXDMA RDC Group Information for Port\t %d \n",
1122	    nxgep->function_num);
1123
1124	rdc_grp = p_cfgp->def_mac_rxdma_grpid;
1125	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
1126		/* The following may work even if we cannot get a large buf. */
1127		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
1128		return (0);
1129	}
1130
1131	buf_len = buff_alloc_size;
1132	mp->b_cont = np;
1133	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
1134	    "Total RDC Groups\t %d \n"
1135	    "default RDC group\t %d\n",
1136	    p_cfgp->max_rdc_grpids,
1137	    p_cfgp->def_mac_rxdma_grpid);
1138
1139	((mblk_t *)np)->b_wptr += print_len;
1140	buf_len -= print_len;
1141
1142	for (i = 0; i < NXGE_MAX_RDC_GROUPS; i++) {
1143		if (p_cfgp->grpids[i]) {
1144			rdc_grp_p = &p_dma_cfgp->rdc_grps[i];
1145			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1146			    buf_len,
1147			    "\nRDC Group Info for Group [%d] %d\n"
1148			    "RDC Count %d\tstart RDC %d\n"
1149			    "RDC Group Population Information"
1150			    " (offsets 0 - 15)\n",
1151			    i, rdc_grp, rdc_grp_p->max_rdcs,
1152			    rdc_grp_p->start_rdc);
1153
1154			((mblk_t *)np)->b_wptr += print_len;
1155			buf_len -= print_len;
1156			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1157			    buf_len, "\n");
1158			((mblk_t *)np)->b_wptr += print_len;
1159			buf_len -= print_len;
1160
1161			for (rdc = 0; rdc < rdc_grp_p->max_rdcs; rdc++) {
1162				print_len = snprintf(
1163				    (char *)((mblk_t *)np)->b_wptr,
1164				    buf_len, "[%d]=%d ", rdc,
1165				    rdc_grp_p->start_rdc + rdc);
1166				((mblk_t *)np)->b_wptr += print_len;
1167				buf_len -= print_len;
1168			}
1169			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1170			    buf_len, "\n");
1171			((mblk_t *)np)->b_wptr += print_len;
1172			buf_len -= print_len;
1173
1174			for (offset = 0; offset < 16; offset++) {
1175				print_len = snprintf(
1176				    (char *)((mblk_t *)np)->b_wptr,
1177				    buf_len, " %c",
1178				    rdc_grp_p->map & (1 << offset) ?
1179				    '1' : '0');
1180				((mblk_t *)np)->b_wptr += print_len;
1181				buf_len -= print_len;
1182			}
1183			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1184			    buf_len, "\n");
1185			((mblk_t *)np)->b_wptr += print_len;
1186			buf_len -= print_len;
1187		}
1188	}
1189	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1190	    "<== nxge_param_get_rxdma_rdcgrp_info"));
1191	return (0);
1192}
1193
1194int
1195nxge_mk_mblk_tail_space(p_mblk_t mp, p_mblk_t *nmp, size_t size)
1196{
1197	p_mblk_t tmp;
1198
1199	tmp = mp;
1200	while (tmp->b_cont)
1201		tmp = tmp->b_cont;
1202	if ((tmp->b_wptr + size) >= tmp->b_datap->db_lim) {
1203		tmp->b_cont = allocb(1024, BPRI_HI);
1204		tmp = tmp->b_cont;
1205		if (!tmp)
1206			return (ENOMEM);
1207	}
1208
1209	*nmp = tmp;
1210	return (0);
1211}
1212
1213
1214/* ARGSUSED */
1215int
1216nxge_param_set_generic(p_nxge_t nxgep, queue_t *q, mblk_t *mp,
1217    char *value, caddr_t cp)
1218{
1219	char *end;
1220	uint32_t new_value;
1221	p_nxge_param_t pa = (p_nxge_param_t)cp;
1222
1223	NXGE_DEBUG_MSG((nxgep, IOC_CTL, " ==> nxge_param_set_generic"));
1224	new_value = (uint32_t)mi_strtol(value, &end, 10);
1225	if (end == value || new_value < pa->minimum ||
1226	    new_value > pa->maximum) {
1227			return (EINVAL);
1228	}
1229	pa->value = new_value;
1230	NXGE_DEBUG_MSG((nxgep, IOC_CTL, " <== nxge_param_set_generic"));
1231	return (0);
1232}
1233
1234
1235/* ARGSUSED */
1236int
1237nxge_param_set_instance(p_nxge_t nxgep, queue_t *q, mblk_t *mp,
1238    char *value, caddr_t cp)
1239{
1240	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " ==> nxge_param_set_instance"));
1241	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " <== nxge_param_set_instance"));
1242	return (0);
1243}
1244
1245
1246/* ARGSUSED */
1247int
1248nxge_param_set_mac(p_nxge_t nxgep, queue_t *q, mblk_t *mp,
1249    char *value, caddr_t cp)
1250{
1251	char		*end;
1252	uint32_t	new_value;
1253	int		status = 0;
1254	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1255
1256	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_mac"));
1257	new_value = (uint32_t)mi_strtol(value, &end, BASE_DECIMAL);
1258	if (PARAM_OUTOF_RANGE(value, end, new_value, pa)) {
1259		return (EINVAL);
1260	}
1261
1262	if (pa->value != new_value) {
1263		pa->old_value = pa->value;
1264		pa->value = new_value;
1265	}
1266
1267	if (!nxge_param_link_update(nxgep)) {
1268		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1269		    " false ret from nxge_param_link_update"));
1270		status = EINVAL;
1271	}
1272
1273	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_mac"));
1274	return (status);
1275}
1276
1277/* ARGSUSED */
1278int
1279nxge_param_rx_intr_pkts(p_nxge_t nxgep, queue_t *q, mblk_t *mp,
1280    char *value, caddr_t cp)
1281{
1282	char		*end;
1283	uint32_t	cfg_value;
1284	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1285
1286	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_rx_intr_pkts"));
1287
1288	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
1289
1290	if ((cfg_value > NXGE_RDC_RCR_THRESHOLD_MAX) ||
1291	    (cfg_value < NXGE_RDC_RCR_THRESHOLD_MIN)) {
1292		return (EINVAL);
1293	}
1294
1295	if ((pa->value != cfg_value)) {
1296		pa->old_value = pa->value;
1297		pa->value = cfg_value;
1298		nxgep->intr_threshold = pa->value;
1299	}
1300
1301	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_rx_intr_pkts"));
1302	return (0);
1303}
1304
1305/* ARGSUSED */
1306int
1307nxge_param_rx_intr_time(p_nxge_t nxgep, queue_t *q, mblk_t *mp,
1308    char *value, caddr_t cp)
1309{
1310	char		*end;
1311	uint32_t	cfg_value;
1312	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1313
1314	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_rx_intr_time"));
1315
1316	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
1317
1318	if ((cfg_value > NXGE_RDC_RCR_TIMEOUT_MAX) ||
1319	    (cfg_value < NXGE_RDC_RCR_TIMEOUT_MIN)) {
1320		return (EINVAL);
1321	}
1322
1323	if ((pa->value != cfg_value)) {
1324		pa->old_value = pa->value;
1325		pa->value = cfg_value;
1326		nxgep->intr_timeout = pa->value;
1327	}
1328
1329	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_rx_intr_time"));
1330	return (0);
1331}
1332
1333/* ARGSUSED */
1334static int
1335nxge_param_set_mac_rdcgrp(p_nxge_t nxgep, queue_t *q,
1336    mblk_t *mp, char *value, caddr_t cp)
1337{
1338	char			 *end;
1339	uint32_t		status = 0, cfg_value;
1340	p_nxge_param_t		pa = (p_nxge_param_t)cp;
1341	uint32_t		cfg_it = B_FALSE;
1342	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1343	p_nxge_hw_pt_cfg_t	p_cfgp;
1344	uint32_t		*val_ptr, *old_val_ptr;
1345	nxge_param_map_t	*mac_map;
1346	p_nxge_class_pt_cfg_t	p_class_cfgp;
1347	nxge_mv_cfg_t		*mac_host_info;
1348
1349	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_mac_rdcgrp "));
1350
1351	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1352	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1353	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1354	mac_host_info = (nxge_mv_cfg_t	*)&p_class_cfgp->mac_host_info[0];
1355	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1356
1357	/*
1358	 * now do decoding
1359	 */
1360	mac_map = (nxge_param_map_t *)&cfg_value;
1361	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " cfg_value %x id %x map_to %x",
1362	    cfg_value, mac_map->param_id, mac_map->map_to));
1363
1364	if ((mac_map->param_id < p_cfgp->max_macs) &&
1365	    p_cfgp->grpids[mac_map->map_to]) {
1366		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1367		    " nxge_param_set_mac_rdcgrp mapping"
1368		    " id %d grp %d", mac_map->param_id, mac_map->map_to));
1369#if defined(__i386)
1370		val_ptr = (uint32_t *)(uint32_t)pa->value;
1371#else
1372		val_ptr = (uint32_t *)pa->value;
1373#endif
1374#if defined(__i386)
1375		old_val_ptr = (uint32_t *)(uint32_t)pa->old_value;
1376#else
1377		old_val_ptr = (uint32_t *)pa->old_value;
1378#endif
1379		if (val_ptr[mac_map->param_id] != cfg_value) {
1380			old_val_ptr[mac_map->param_id] =
1381			    val_ptr[mac_map->param_id];
1382			val_ptr[mac_map->param_id] = cfg_value;
1383			mac_host_info[mac_map->param_id].mpr_npr =
1384			    mac_map->pref;
1385			mac_host_info[mac_map->param_id].flag = 1;
1386			mac_host_info[mac_map->param_id].rdctbl =
1387			    mac_map->map_to;
1388			cfg_it = B_TRUE;
1389		}
1390	} else {
1391		return (EINVAL);
1392	}
1393
1394	if (cfg_it == B_TRUE) {
1395		status = nxge_logical_mac_assign_rdc_table(nxgep,
1396		    (uint8_t)mac_map->param_id);
1397		if (status != NXGE_OK)
1398			return (EINVAL);
1399	}
1400
1401	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_mac_rdcgrp"));
1402	return (0);
1403}
1404
1405/* ARGSUSED */
1406static int
1407nxge_param_set_vlan_rdcgrp(p_nxge_t nxgep, queue_t *q,
1408    mblk_t *mp, char *value, caddr_t cp)
1409{
1410	char			*end;
1411	uint32_t		status = 0, cfg_value;
1412	p_nxge_param_t		pa = (p_nxge_param_t)cp;
1413	uint32_t		cfg_it = B_FALSE;
1414	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1415	p_nxge_hw_pt_cfg_t	p_cfgp;
1416	uint32_t		*val_ptr, *old_val_ptr;
1417	nxge_param_map_t	*vmap, *old_map;
1418	p_nxge_class_pt_cfg_t	p_class_cfgp;
1419	uint64_t		cfgd_vlans;
1420	int			i, inc = 0, cfg_position;
1421	nxge_mv_cfg_t		*vlan_tbl;
1422
1423	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_vlan_rdcgrp "));
1424
1425	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1426	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1427	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1428	vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0];
1429
1430	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1431
1432	/* now do decoding */
1433	cfgd_vlans = ((pa->type &  NXGE_PARAM_ARRAY_CNT_MASK) >>
1434	    NXGE_PARAM_ARRAY_CNT_SHIFT);
1435
1436	if (cfgd_vlans == NXGE_PARAM_ARRAY_INIT_SIZE) {
1437		/*
1438		 * for now, we process only upto max
1439		 * NXGE_PARAM_ARRAY_INIT_SIZE parameters
1440		 * In the future, we may want to expand
1441		 * the storage array and continue
1442		 */
1443		return (EINVAL);
1444	}
1445
1446	vmap = (nxge_param_map_t *)&cfg_value;
1447	if ((vmap->param_id) &&
1448	    (vmap->param_id < NXGE_MAX_VLANS) &&
1449	    (vmap->map_to < p_cfgp->max_rdc_grpids)) {
1450		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1451		    "nxge_param_set_vlan_rdcgrp mapping"
1452		    " id %d grp %d",
1453		    vmap->param_id, vmap->map_to));
1454#if defined(__i386)
1455		val_ptr = (uint32_t *)(uint32_t)pa->value;
1456#else
1457		val_ptr = (uint32_t *)pa->value;
1458#endif
1459#if defined(__i386)
1460		old_val_ptr = (uint32_t *)(uint32_t)pa->old_value;
1461#else
1462		old_val_ptr = (uint32_t *)pa->old_value;
1463#endif
1464
1465		/* search to see if this vlan id is already configured */
1466		for (i = 0; i < cfgd_vlans; i++) {
1467			old_map = (nxge_param_map_t *)&val_ptr[i];
1468			if ((old_map->param_id == 0) ||
1469			    (vmap->param_id == old_map->param_id) ||
1470			    (vlan_tbl[vmap->param_id].flag)) {
1471				cfg_position = i;
1472				break;
1473			}
1474		}
1475
1476		if (cfgd_vlans == 0) {
1477			cfg_position = 0;
1478			inc++;
1479		}
1480
1481		if (i == cfgd_vlans) {
1482			cfg_position = i;
1483			inc++;
1484		}
1485
1486		NXGE_DEBUG_MSG((nxgep, NDD2_CTL,
1487		    "set_vlan_rdcgrp mapping"
1488		    " i %d cfgd_vlans %llx position %d ",
1489		    i, cfgd_vlans, cfg_position));
1490		if (val_ptr[cfg_position] != cfg_value) {
1491			old_val_ptr[cfg_position] = val_ptr[cfg_position];
1492			val_ptr[cfg_position] = cfg_value;
1493			vlan_tbl[vmap->param_id].mpr_npr = vmap->pref;
1494			vlan_tbl[vmap->param_id].flag = 1;
1495			vlan_tbl[vmap->param_id].rdctbl =
1496			    vmap->map_to + p_cfgp->def_mac_rxdma_grpid;
1497			cfg_it = B_TRUE;
1498			if (inc) {
1499				cfgd_vlans++;
1500				pa->type &= ~NXGE_PARAM_ARRAY_CNT_MASK;
1501				pa->type |= (cfgd_vlans <<
1502				    NXGE_PARAM_ARRAY_CNT_SHIFT);
1503
1504			}
1505			NXGE_DEBUG_MSG((nxgep, NDD2_CTL,
1506			    "after: param_set_vlan_rdcgrp "
1507			    " cfg_vlans %llx position %d \n",
1508			    cfgd_vlans, cfg_position));
1509		}
1510	} else {
1511		return (EINVAL);
1512	}
1513
1514	if (cfg_it == B_TRUE) {
1515		status = nxge_fflp_config_vlan_table(nxgep,
1516		    (uint16_t)vmap->param_id);
1517		if (status != NXGE_OK)
1518			return (EINVAL);
1519	}
1520
1521	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_vlan_rdcgrp"));
1522	return (0);
1523}
1524
1525/* ARGSUSED */
1526static int
1527nxge_param_get_vlan_rdcgrp(p_nxge_t nxgep, queue_t *q,
1528    mblk_t *mp, caddr_t cp)
1529{
1530
1531	uint_t 			print_len, buf_len;
1532	p_mblk_t		np;
1533	int			i;
1534	uint32_t		*val_ptr;
1535	nxge_param_map_t	*vmap;
1536	p_nxge_param_t		pa = (p_nxge_param_t)cp;
1537	p_nxge_class_pt_cfg_t 	p_class_cfgp;
1538	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1539	p_nxge_hw_pt_cfg_t	p_cfgp;
1540	uint64_t		cfgd_vlans = 0;
1541	nxge_mv_cfg_t		*vlan_tbl;
1542	int			buff_alloc_size =
1543	    NXGE_NDD_INFODUMP_BUFF_SIZE * 32;
1544
1545	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_vlan_rdcgrp "));
1546	(void) mi_mpprintf(mp, "VLAN RDC Mapping Information for Port\t %d \n",
1547	    nxgep->function_num);
1548
1549	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
1550		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
1551		return (0);
1552	}
1553
1554	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1555	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1556
1557	buf_len = buff_alloc_size;
1558	mp->b_cont = np;
1559	cfgd_vlans = (pa->type &  NXGE_PARAM_ARRAY_CNT_MASK) >>
1560	    NXGE_PARAM_ARRAY_CNT_SHIFT;
1561
1562	i = (int)cfgd_vlans;
1563	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1564	vlan_tbl = (nxge_mv_cfg_t *)&p_class_cfgp->vlan_tbl[0];
1565	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
1566	    "Configured VLANs %d\n"
1567	    "VLAN ID\t RDC GRP (Actual/Port)\t"
1568	    " Prefernce\n", i);
1569	((mblk_t *)np)->b_wptr += print_len;
1570	buf_len -= print_len;
1571#if defined(__i386)
1572	val_ptr = (uint32_t *)(uint32_t)pa->value;
1573#else
1574	val_ptr = (uint32_t *)pa->value;
1575#endif
1576
1577	for (i = 0; i < cfgd_vlans; i++) {
1578		vmap = (nxge_param_map_t *)&val_ptr[i];
1579		if (p_class_cfgp->vlan_tbl[vmap->param_id].flag) {
1580			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1581			    buf_len,
1582			    "  %d\t\t %d/%d\t\t %d\n",
1583			    vmap->param_id,
1584			    vlan_tbl[vmap->param_id].rdctbl,
1585			    vlan_tbl[vmap->param_id].rdctbl -
1586			    p_cfgp->def_mac_rxdma_grpid,
1587			    vlan_tbl[vmap->param_id].mpr_npr);
1588			((mblk_t *)np)->b_wptr += print_len;
1589			buf_len -= print_len;
1590		}
1591	}
1592
1593	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_vlan_rdcgrp"));
1594	return (0);
1595}
1596
1597/* ARGSUSED */
1598static int
1599nxge_param_get_mac_rdcgrp(p_nxge_t nxgep, queue_t *q,
1600    mblk_t *mp, caddr_t cp)
1601{
1602	uint_t			print_len, buf_len;
1603	p_mblk_t		np;
1604	int			i;
1605	p_nxge_class_pt_cfg_t 	p_class_cfgp;
1606	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1607	p_nxge_hw_pt_cfg_t	p_cfgp;
1608	nxge_mv_cfg_t		*mac_host_info;
1609
1610	int buff_alloc_size = NXGE_NDD_INFODUMP_BUFF_SIZE * 32;
1611	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_mac_rdcgrp "));
1612	(void) mi_mpprintf(mp,
1613	    "MAC ADDR RDC Mapping Information for Port\t %d\n",
1614	    nxgep->function_num);
1615
1616	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
1617		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
1618		return (0);
1619	}
1620
1621	buf_len = buff_alloc_size;
1622	mp->b_cont = np;
1623	p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config;
1624	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1625	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1626	mac_host_info = (nxge_mv_cfg_t	*)&p_class_cfgp->mac_host_info[0];
1627	print_len = snprintf((char *)np->b_wptr, buf_len,
1628	    "MAC ID\t RDC GRP (Actual/Port)\t"
1629	    " Prefernce\n");
1630	((mblk_t *)np)->b_wptr += print_len;
1631	buf_len -= print_len;
1632	for (i = 0; i < p_cfgp->max_macs; i++) {
1633		if (mac_host_info[i].flag) {
1634			print_len = snprintf((char *)((mblk_t *)np)->b_wptr,
1635			    buf_len,
1636			    "   %d\t  %d/%d\t\t %d\n",
1637			    i, mac_host_info[i].rdctbl,
1638			    mac_host_info[i].rdctbl -
1639			    p_cfgp->def_mac_rxdma_grpid,
1640			    mac_host_info[i].mpr_npr);
1641			((mblk_t *)np)->b_wptr += print_len;
1642			buf_len -= print_len;
1643		}
1644	}
1645	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
1646	    "Done Info Dumping \n");
1647	((mblk_t *)np)->b_wptr += print_len;
1648	buf_len -= print_len;
1649	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_macrdcgrp"));
1650	return (0);
1651}
1652
1653/* ARGSUSED */
1654static int
1655nxge_param_tcam_enable(p_nxge_t nxgep, queue_t *q,
1656    mblk_t *mp, char *value, caddr_t cp)
1657{
1658	uint32_t	status = 0, cfg_value;
1659	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1660	uint32_t	cfg_it = B_FALSE;
1661	char		*end;
1662
1663	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_tcam_enable"));
1664
1665	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_BINARY);
1666	if (pa->value != cfg_value) {
1667		pa->old_value = pa->value;
1668		pa->value = cfg_value;
1669		cfg_it = B_TRUE;
1670	}
1671
1672	if (cfg_it == B_TRUE) {
1673		if (pa->value)
1674			status = nxge_fflp_config_tcam_enable(nxgep);
1675		else
1676			status = nxge_fflp_config_tcam_disable(nxgep);
1677		if (status != NXGE_OK)
1678			return (EINVAL);
1679	}
1680
1681	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " <== nxge_param_tcam_enable"));
1682	return (0);
1683}
1684
1685/* ARGSUSED */
1686static int
1687nxge_param_hash_lookup_enable(p_nxge_t nxgep, queue_t *q,
1688    mblk_t *mp, char *value, caddr_t cp)
1689{
1690	uint32_t	status = 0, cfg_value;
1691	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1692	uint32_t	cfg_it = B_FALSE;
1693	char		*end;
1694
1695	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_hash_lookup_enable"));
1696
1697	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_BINARY);
1698	if (pa->value != cfg_value) {
1699		pa->old_value = pa->value;
1700		pa->value = cfg_value;
1701		cfg_it = B_TRUE;
1702	}
1703
1704	if (cfg_it == B_TRUE) {
1705		if (pa->value)
1706			status = nxge_fflp_config_hash_lookup_enable(nxgep);
1707		else
1708			status = nxge_fflp_config_hash_lookup_disable(nxgep);
1709		if (status != NXGE_OK)
1710			return (EINVAL);
1711	}
1712
1713	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " <== nxge_param_hash_lookup_enable"));
1714	return (0);
1715}
1716
1717/* ARGSUSED */
1718static int
1719nxge_param_llc_snap_enable(p_nxge_t nxgep, queue_t *q,
1720    mblk_t *mp, char *value, caddr_t cp)
1721{
1722	char		*end;
1723	uint32_t	status = 0, cfg_value;
1724	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1725	uint32_t	cfg_it = B_FALSE;
1726
1727	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_llc_snap_enable"));
1728
1729	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_BINARY);
1730	if (pa->value != cfg_value) {
1731		pa->old_value = pa->value;
1732		pa->value = cfg_value;
1733		cfg_it = B_TRUE;
1734	}
1735
1736	if (cfg_it == B_TRUE) {
1737		if (pa->value)
1738			status = nxge_fflp_config_tcam_enable(nxgep);
1739		else
1740			status = nxge_fflp_config_tcam_disable(nxgep);
1741		if (status != NXGE_OK)
1742			return (EINVAL);
1743	}
1744
1745	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " <== nxge_param_llc_snap_enable"));
1746	return (0);
1747}
1748
1749/* ARGSUSED */
1750static int
1751nxge_param_set_ether_usr(p_nxge_t nxgep, queue_t *q,
1752    mblk_t *mp, char *value, caddr_t cp)
1753{
1754	char		*end;
1755	uint32_t	status = 0, cfg_value;
1756	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1757	uint8_t		cfg_it = B_FALSE;
1758
1759	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_ether_usr"));
1760
1761	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1762	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1763		return (EINVAL);
1764	}
1765
1766	if (pa->value != cfg_value) {
1767		pa->old_value = pa->value;
1768		pa->value = cfg_value;
1769		cfg_it = B_TRUE;
1770	}
1771
1772	/* do the actual hw setup  */
1773	if (cfg_it == B_TRUE) {
1774		(void) mi_strtol(pa->name, &end, BASE_DECIMAL);
1775		NXGE_DEBUG_MSG((nxgep, NDD_CTL, " nxge_param_set_ether_usr"));
1776	}
1777
1778	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_ether_usr"));
1779	return (status);
1780}
1781
1782/* ARGSUSED */
1783static int
1784nxge_param_set_ip_usr(p_nxge_t nxgep, queue_t *q,
1785    mblk_t *mp, char *value, caddr_t cp)
1786{
1787	char		*end;
1788	tcam_class_t	class;
1789	uint32_t	status, cfg_value;
1790	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1791	uint32_t	cfg_it = B_FALSE;
1792
1793	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_ip_usr"));
1794
1795	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1796	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1797		return (EINVAL);
1798	}
1799
1800	if (pa->value != cfg_value) {
1801		pa->old_value = pa->value;
1802		pa->value = cfg_value;
1803		cfg_it = B_TRUE;
1804	}
1805
1806	/* do the actual hw setup with cfg_value. */
1807	if (cfg_it == B_TRUE) {
1808		class = mi_strtol(pa->name, &end, 10);
1809		status = nxge_fflp_ip_usr_class_config(nxgep, class, pa->value);
1810	}
1811
1812	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_ip_usr"));
1813	return (status);
1814}
1815
1816/* ARGSUSED */
1817static int
1818nxge_class_name_2value(p_nxge_t nxgep, char *name)
1819{
1820	int		i;
1821	int		class_instance = param_class_opt_ip_usr4;
1822	p_nxge_param_t	param_arr;
1823
1824	param_arr = nxgep->param_arr;
1825	for (i = TCAM_CLASS_IP_USER_4; i <= TCAM_CLASS_SCTP_IPV6; i++) {
1826		if (strcmp(param_arr[class_instance].name, name) == 0)
1827			return (i);
1828		class_instance++;
1829	}
1830	return (-1);
1831}
1832
1833/* ARGSUSED */
1834int
1835nxge_param_set_ip_opt(p_nxge_t nxgep, queue_t *q,
1836    mblk_t *mp, char *value, caddr_t cp)
1837{
1838	char		*end;
1839	uint32_t	status, cfg_value;
1840	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1841	tcam_class_t	class;
1842	uint32_t	cfg_it = B_FALSE;
1843
1844	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_ip_opt"));
1845
1846	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1847	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1848		return (EINVAL);
1849	}
1850
1851	if (pa->value != cfg_value) {
1852		pa->old_value = pa->value;
1853		pa->value = cfg_value;
1854		cfg_it = B_TRUE;
1855	}
1856
1857	if (cfg_it == B_TRUE) {
1858		/* do the actual hw setup  */
1859		class = nxge_class_name_2value(nxgep, pa->name);
1860		if (class == -1)
1861			return (EINVAL);
1862
1863		/* Filter out the allowed bits */
1864		pa->value &= (NXGE_CLASS_FLOW_USE_PORTNUM |
1865		    NXGE_CLASS_FLOW_USE_L2DA | NXGE_CLASS_FLOW_USE_VLAN |
1866		    NXGE_CLASS_FLOW_USE_PROTO | NXGE_CLASS_FLOW_USE_IPSRC |
1867		    NXGE_CLASS_FLOW_USE_IPDST | NXGE_CLASS_FLOW_USE_SRC_PORT |
1868		    NXGE_CLASS_FLOW_USE_DST_PORT);
1869
1870		status = nxge_fflp_ip_class_config(nxgep, class, pa->value);
1871		if (status != NXGE_OK)
1872			return (EINVAL);
1873	}
1874
1875	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_ip_opt"));
1876	return (0);
1877}
1878
1879/* ARGSUSED */
1880static int
1881nxge_param_get_ip_opt(p_nxge_t nxgep, queue_t *q,
1882    mblk_t *mp, caddr_t cp)
1883{
1884	uint32_t status, cfg_value;
1885	p_nxge_param_t pa = (p_nxge_param_t)cp;
1886	tcam_class_t class;
1887
1888	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_ip_opt"));
1889
1890	/* do the actual hw setup  */
1891	class = nxge_class_name_2value(nxgep, pa->name);
1892	if (class == -1)
1893		return (EINVAL);
1894
1895	cfg_value = 0;
1896	status = nxge_fflp_ip_class_config_get(nxgep, class, &cfg_value);
1897	if (status != NXGE_OK)
1898		return (EINVAL);
1899
1900	/* Filter out the allowed bits */
1901	cfg_value &= (NXGE_CLASS_FLOW_USE_PORTNUM | NXGE_CLASS_FLOW_USE_L2DA |
1902	    NXGE_CLASS_FLOW_USE_VLAN | NXGE_CLASS_FLOW_USE_PROTO |
1903	    NXGE_CLASS_FLOW_USE_IPSRC | NXGE_CLASS_FLOW_USE_IPDST |
1904	    NXGE_CLASS_FLOW_USE_SRC_PORT | NXGE_CLASS_FLOW_USE_DST_PORT);
1905
1906	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1907	    "nxge_param_get_ip_opt_get %x ", cfg_value));
1908
1909	pa->value = cfg_value;
1910	(void) mi_mpprintf(mp, "%x", cfg_value);
1911
1912	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_ip_opt status "));
1913	return (0);
1914}
1915
1916/* ARGSUSED */
1917static int
1918nxge_param_fflp_hash_init(p_nxge_t nxgep, queue_t *q,
1919    mblk_t *mp, char *value, caddr_t cp)
1920{
1921	char		*end;
1922	uint32_t	status, cfg_value;
1923	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1924	tcam_class_t	class;
1925	uint32_t	cfg_it = B_FALSE;
1926
1927	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_fflp_hash_init"));
1928
1929	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1930	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1931		return (EINVAL);
1932	}
1933
1934	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1935	    "nxge_param_fflp_hash_init value %x", cfg_value));
1936
1937	if (pa->value != cfg_value) {
1938		pa->old_value = pa->value;
1939		pa->value = cfg_value;
1940		cfg_it = B_TRUE;
1941	}
1942
1943	if (cfg_it == B_TRUE) {
1944		char *h_name;
1945
1946		/* do the actual hw setup */
1947		h_name = pa->name;
1948		h_name++;
1949		class = mi_strtol(h_name, &end, 10);
1950		switch (class) {
1951			case 1:
1952				status = nxge_fflp_set_hash1(nxgep,
1953				    (uint32_t)pa->value);
1954				break;
1955			case 2:
1956				status = nxge_fflp_set_hash2(nxgep,
1957				    (uint16_t)pa->value);
1958				break;
1959
1960			default:
1961			NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1962			    " nxge_param_fflp_hash_init"
1963			    " %s Wrong hash var %d",
1964			    pa->name, class));
1965			return (EINVAL);
1966		}
1967		if (status != NXGE_OK)
1968			return (EINVAL);
1969	}
1970
1971	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " <== nxge_param_fflp_hash_init"));
1972	return (0);
1973}
1974
1975/* ARGSUSED */
1976static int
1977nxge_param_set_grp_rdc(p_nxge_t nxgep, queue_t *q,
1978    mblk_t *mp, char *value, caddr_t cp)
1979{
1980	char			*end;
1981	uint32_t		status = 0, cfg_value;
1982	p_nxge_param_t		pa = (p_nxge_param_t)cp;
1983	uint32_t		cfg_it = B_FALSE;
1984	int			rdc_grp;
1985	uint8_t			real_rdc;
1986	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1987	p_nxge_hw_pt_cfg_t	p_cfgp;
1988	p_nxge_rdc_grp_t	rdc_grp_p;
1989
1990	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1991	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1992
1993	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_grp_rdc"));
1994
1995	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
1996	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1997		return (EINVAL);
1998	}
1999
2000	if (cfg_value >= p_cfgp->max_rdcs) {
2001		return (EINVAL);
2002	}
2003
2004	if (pa->value != cfg_value) {
2005		pa->old_value = pa->value;
2006		pa->value = cfg_value;
2007		cfg_it = B_TRUE;
2008	}
2009
2010	if (cfg_it == B_TRUE) {
2011		char *grp_name;
2012		grp_name = pa->name;
2013		grp_name += strlen("default-grp");
2014		rdc_grp = mi_strtol(grp_name, &end, 10);
2015		rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp];
2016		real_rdc = rdc_grp_p->start_rdc + cfg_value;
2017		if (nxge_check_rxdma_rdcgrp_member(nxgep, rdc_grp,
2018		    cfg_value) == B_FALSE) {
2019			pa->value = pa->old_value;
2020			NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2021			    " nxge_param_set_grp_rdc"
2022			    " %d read %d actual %d outof range",
2023			    rdc_grp, cfg_value, real_rdc));
2024			return (EINVAL);
2025		}
2026		status = nxge_rxdma_cfg_rdcgrp_default_rdc(nxgep, rdc_grp,
2027		    real_rdc);
2028		if (status != NXGE_OK)
2029			return (EINVAL);
2030	}
2031
2032	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_grp_rdc"));
2033	return (0);
2034}
2035
2036/* ARGSUSED */
2037static int
2038nxge_param_set_port_rdc(p_nxge_t nxgep, queue_t *q,
2039    mblk_t *mp, char *value, caddr_t cp)
2040{
2041	char		*end;
2042	uint32_t	status = B_TRUE, cfg_value;
2043	p_nxge_param_t	pa = (p_nxge_param_t)cp;
2044	uint32_t	cfg_it = B_FALSE;
2045
2046	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
2047	p_nxge_hw_pt_cfg_t	p_cfgp;
2048
2049	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_port_rdc"));
2050	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
2051	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
2052
2053	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
2054	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2055		return (EINVAL);
2056	}
2057
2058	if (pa->value != cfg_value) {
2059		if (cfg_value >= p_cfgp->max_rdcs)
2060			return (EINVAL);
2061		pa->old_value = pa->value;
2062		pa->value = cfg_value;
2063		cfg_it = B_TRUE;
2064	}
2065
2066	if (cfg_it == B_TRUE) {
2067		int rdc;
2068		if ((rdc = nxge_dci_map(nxgep, VP_BOUND_RX, cfg_value)) < 0)
2069			return (EINVAL);
2070		status = nxge_rxdma_cfg_port_default_rdc(nxgep,
2071		    nxgep->function_num, rdc);
2072		if (status != NXGE_OK)
2073			return (EINVAL);
2074	}
2075
2076	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_port_rdc"));
2077	return (0);
2078}
2079
2080/* ARGSUSED */
2081static int
2082nxge_param_set_nxge_debug_flag(p_nxge_t nxgep, queue_t *q,
2083    mblk_t *mp, char *value, caddr_t cp)
2084{
2085	char *end;
2086	uint32_t status = 0;
2087	uint64_t cfg_value = 0;
2088	p_nxge_param_t pa = (p_nxge_param_t)cp;
2089	uint32_t cfg_it = B_FALSE;
2090
2091	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_nxge_debug_flag"));
2092	cfg_value = mi_strtol(value, &end, BASE_HEX);
2093
2094	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2095		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2096		    " nxge_param_set_nxge_debug_flag"
2097		    " outof range %llx", cfg_value));
2098		return (EINVAL);
2099	}
2100	if (pa->value != cfg_value) {
2101		pa->old_value = pa->value;
2102		pa->value = cfg_value;
2103		cfg_it = B_TRUE;
2104	}
2105
2106	if (cfg_it == B_TRUE) {
2107		nxgep->nxge_debug_level = pa->value;
2108	}
2109
2110	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_nxge_debug_flag"));
2111	return (status);
2112}
2113
2114/* ARGSUSED */
2115static int
2116nxge_param_get_debug_flag(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2117{
2118	int		status = 0;
2119	p_nxge_param_t	pa = (p_nxge_param_t)cp;
2120
2121	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_debug_flag"));
2122
2123	if (pa->value > 0xffffffff)
2124		(void) mi_mpprintf(mp, "%x%x",  (int)(pa->value >> 32),
2125		    (int)(pa->value & 0xffffffff));
2126	else
2127		(void) mi_mpprintf(mp, "%x", (int)pa->value);
2128
2129	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_debug_flag"));
2130	return (status);
2131}
2132
2133/* ARGSUSED */
2134static int
2135nxge_param_set_npi_debug_flag(p_nxge_t nxgep, queue_t *q,
2136    mblk_t *mp, char *value, caddr_t cp)
2137{
2138	char		*end;
2139	uint32_t	status = 0;
2140	uint64_t	 cfg_value = 0;
2141	p_nxge_param_t	pa;
2142	uint32_t	cfg_it = B_FALSE;
2143
2144	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_npi_debug_flag"));
2145	cfg_value = mi_strtol(value, &end, BASE_HEX);
2146	pa = (p_nxge_param_t)cp;
2147	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2148		NXGE_DEBUG_MSG((nxgep, NDD_CTL, " nxge_param_set_npi_debug_flag"
2149		    " outof range %llx", cfg_value));
2150		return (EINVAL);
2151	}
2152	if (pa->value != cfg_value) {
2153		pa->old_value = pa->value;
2154		pa->value = cfg_value;
2155		cfg_it = B_TRUE;
2156	}
2157
2158	if (cfg_it == B_TRUE) {
2159		npi_debug_level = pa->value;
2160	}
2161	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_debug_flag"));
2162	return (status);
2163}
2164
2165/* ARGSUSED */
2166static int
2167nxge_param_dump_rdc(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2168{
2169	nxge_grp_set_t *set = &nxgep->rx_set;
2170	int rdc;
2171
2172	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_rdc"));
2173
2174	if (!isLDOMguest(nxgep))
2175		(void) npi_rxdma_dump_fzc_regs(NXGE_DEV_NPI_HANDLE(nxgep));
2176
2177	for (rdc = 0; rdc < NXGE_MAX_TDCS; rdc++) {
2178		if ((1 << rdc) & set->owned.map) {
2179			(void) nxge_dump_rxdma_channel(nxgep, rdc);
2180		}
2181	}
2182
2183	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_rdc"));
2184	return (0);
2185}
2186
2187/* ARGSUSED */
2188static int
2189nxge_param_dump_tdc(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2190{
2191	nxge_grp_set_t *set = &nxgep->tx_set;
2192	int tdc;
2193
2194	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_tdc"));
2195
2196	for (tdc = 0; tdc < NXGE_MAX_TDCS; tdc++) {
2197		if ((1 << tdc) & set->owned.map) {
2198			(void) nxge_txdma_regs_dump(nxgep, tdc);
2199		}
2200	}
2201
2202	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_tdc"));
2203	return (0);
2204}
2205
2206/* ARGSUSED */
2207static int
2208nxge_param_dump_fflp_regs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2209{
2210	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_fflp_regs"));
2211
2212	(void) npi_fflp_dump_regs(NXGE_DEV_NPI_HANDLE(nxgep));
2213
2214	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_fflp_regs"));
2215	return (0);
2216}
2217
2218/* ARGSUSED */
2219static int
2220nxge_param_dump_mac_regs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2221{
2222	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_mac_regs"));
2223
2224	(void) npi_mac_dump_regs(NXGE_DEV_NPI_HANDLE(nxgep),
2225	    nxgep->function_num);
2226
2227	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_mac_regs"));
2228	return (0);
2229}
2230
2231/* ARGSUSED */
2232static int
2233nxge_param_dump_ipp_regs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2234{
2235	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_ipp_regs"));
2236
2237	(void) npi_ipp_dump_regs(NXGE_DEV_NPI_HANDLE(nxgep),
2238	    nxgep->function_num);
2239	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_ipp_regs"));
2240	return (0);
2241}
2242
2243/* ARGSUSED */
2244static int
2245nxge_param_dump_vlan_table(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2246{
2247	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_dump_vlan_table"));
2248
2249	(void) npi_fflp_vlan_tbl_dump(NXGE_DEV_NPI_HANDLE(nxgep));
2250
2251	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_dump_vlan_table"));
2252	return (0);
2253}
2254
2255/* ARGSUSED */
2256static int
2257nxge_param_dump_rdc_table(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2258{
2259	uint8_t	table;
2260
2261	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_dump_rdc_table"));
2262	for (table = 0; table < NXGE_MAX_RDC_GROUPS; table++) {
2263		(void) npi_rxdma_dump_rdc_table(NXGE_DEV_NPI_HANDLE(nxgep),
2264		    table);
2265	}
2266
2267	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_dump_rdc_table"));
2268	return (0);
2269}
2270
2271typedef struct block_info {
2272	char		*name;
2273	uint32_t	offset;
2274} block_info_t;
2275
2276block_info_t reg_block[] = {
2277	{"PIO",		PIO},
2278	{"FZC_PIO",	FZC_PIO},
2279	{"FZC_XMAC",	FZC_MAC},
2280	{"FZC_IPP",	FZC_IPP},
2281	{"FFLP",	FFLP},
2282	{"FZC_FFLP",	FZC_FFLP},
2283	{"PIO_VADDR",	PIO_VADDR},
2284	{"ZCP",	ZCP},
2285	{"FZC_ZCP",	FZC_ZCP},
2286	{"DMC",	DMC},
2287	{"FZC_DMC",	FZC_DMC},
2288	{"TXC",	TXC},
2289	{"FZC_TXC",	FZC_TXC},
2290	{"PIO_LDSV",	PIO_LDSV},
2291	{"PIO_LDGIM",	PIO_LDGIM},
2292	{"PIO_IMASK0",	PIO_IMASK0},
2293	{"PIO_IMASK1",	PIO_IMASK1},
2294	{"FZC_PROM",	FZC_PROM},
2295	{"END",	ALL_FF_32},
2296};
2297
2298/* ARGSUSED */
2299static int
2300nxge_param_dump_ptrs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2301{
2302	uint_t			print_len, buf_len;
2303	p_mblk_t		np;
2304	int			rdc, tdc, block;
2305	uint64_t		base;
2306	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
2307	p_nxge_hw_pt_cfg_t	p_cfgp;
2308	int			buff_alloc_size = NXGE_NDD_INFODUMP_BUFF_8K;
2309	p_tx_ring_t 		*tx_rings;
2310	p_rx_rcr_rings_t 	rx_rcr_rings;
2311	p_rx_rcr_ring_t		*rcr_rings;
2312	p_rx_rbr_rings_t 	rx_rbr_rings;
2313	p_rx_rbr_ring_t		*rbr_rings;
2314
2315	NXGE_DEBUG_MSG((nxgep, IOC_CTL,
2316	    "==> nxge_param_dump_ptrs"));
2317
2318	(void) mi_mpprintf(mp, "ptr information for Port\t %d \n",
2319	    nxgep->function_num);
2320
2321	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
2322		/* The following may work even if we cannot get a large buf. */
2323		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
2324		return (0);
2325	}
2326
2327	buf_len = buff_alloc_size;
2328	mp->b_cont = np;
2329	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
2330	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
2331
2332	rx_rcr_rings = nxgep->rx_rcr_rings;
2333	rcr_rings = rx_rcr_rings->rcr_rings;
2334	rx_rbr_rings = nxgep->rx_rbr_rings;
2335	rbr_rings = rx_rbr_rings->rbr_rings;
2336	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2337	    "nxgep (nxge_t) $%p\n"
2338	    "dev_regs (dev_regs_t) $%p\n",
2339	    (void *)nxgep, (void *)nxgep->dev_regs);
2340
2341	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2342
2343	/* do register pointers */
2344	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2345	    "reg base (npi_reg_ptr_t) $%p\t "
2346	    "pci reg (npi_reg_ptr_t) $%p\n",
2347	    (void *)nxgep->dev_regs->nxge_regp,
2348	    (void *)nxgep->dev_regs->nxge_pciregp);
2349
2350	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2351
2352	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2353	    "\nBlock \t Offset \n");
2354
2355	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2356	block = 0;
2357#if defined(__i386)
2358	base = (uint64_t)(uint32_t)nxgep->dev_regs->nxge_regp;
2359#else
2360	base = (uint64_t)nxgep->dev_regs->nxge_regp;
2361#endif
2362	while (reg_block[block].offset != ALL_FF_32) {
2363		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2364		    "%9s\t 0x%llx\n",
2365		    reg_block[block].name,
2366		    (unsigned long long)(reg_block[block].offset + base));
2367		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2368		block++;
2369	}
2370
2371	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2372	    "\nRDC\t rcrp (rx_rcr_ring_t)\t "
2373	    "rbrp (rx_rbr_ring_t)\n");
2374
2375	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2376
2377	for (rdc = 0; rdc < p_cfgp->max_rdcs; rdc++) {
2378		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2379		    " %d\t  $%p\t\t   $%p\n",
2380		    rdc, (void *)rcr_rings[rdc],
2381		    (void *)rbr_rings[rdc]);
2382		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2383	}
2384
2385	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2386	    "\nTDC\t tdcp (tx_ring_t)\n");
2387
2388	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2389	tx_rings = nxgep->tx_rings->rings;
2390	for (tdc = 0; tdc < p_cfgp->tdc.count; tdc++) {
2391		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2392		    " %d\t  $%p\n", tdc, (void *)tx_rings[tdc]);
2393		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2394	}
2395
2396	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, "\n\n");
2397
2398	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2399	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_ptrs"));
2400	return (0);
2401}
2402
2403
2404/* ARGSUSED */
2405int
2406nxge_nd_get_names(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t param)
2407{
2408	ND		*nd;
2409	NDE		*nde;
2410	char		*rwtag;
2411	boolean_t	get_ok, set_ok;
2412	size_t		param_len;
2413	int		status = 0;
2414
2415	nd = (ND *)param;
2416	if (!nd)
2417		return (ENOENT);
2418
2419	for (nde = nd->nd_tbl; nde->nde_name; nde++) {
2420		get_ok = (nde->nde_get_pfi != nxge_get_default) &&
2421		    (nde->nde_get_pfi != NULL);
2422		set_ok = (nde->nde_set_pfi != nxge_set_default) &&
2423		    (nde->nde_set_pfi != NULL);
2424		if (get_ok) {
2425			if (set_ok)
2426				rwtag = "read and write";
2427			else
2428				rwtag = "read only";
2429		} else if (set_ok)
2430			rwtag = "write only";
2431		else {
2432			continue;
2433		}
2434		param_len = strlen(rwtag);
2435		param_len += strlen(nde->nde_name);
2436		param_len += 4;
2437
2438		(void) mi_mpprintf(mp, "%s (%s)", nde->nde_name, rwtag);
2439	}
2440	return (status);
2441}
2442
2443/* ARGSUSED */
2444int
2445nxge_get_default(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t data)
2446{
2447	return (EACCES);
2448}
2449
2450/* ARGSUSED */
2451int
2452nxge_set_default(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, char *value,
2453    caddr_t data)
2454{
2455	return (EACCES);
2456}
2457
2458boolean_t
2459nxge_param_link_update(p_nxge_t nxgep)
2460{
2461	p_nxge_param_t 		param_arr;
2462	nxge_param_index_t 	i;
2463	boolean_t 		update_xcvr;
2464	boolean_t 		update_dev;
2465	int 			instance;
2466	boolean_t 		status = B_TRUE;
2467
2468	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_link_update"));
2469
2470	param_arr = nxgep->param_arr;
2471	instance = nxgep->instance;
2472	update_xcvr = B_FALSE;
2473	for (i = param_anar_1000fdx; i < param_anar_asmpause; i++) {
2474		update_xcvr |= param_arr[i].value;
2475	}
2476
2477	if (update_xcvr) {
2478		update_xcvr = B_FALSE;
2479		for (i = param_autoneg; i < param_enable_ipg0; i++) {
2480			update_xcvr |=
2481			    (param_arr[i].value != param_arr[i].old_value);
2482			param_arr[i].old_value = param_arr[i].value;
2483		}
2484		if (update_xcvr) {
2485			NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2486			    "==> nxge_param_link_update: update xcvr"));
2487			RW_ENTER_WRITER(&nxgep->filter_lock);
2488			(void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP);
2489			(void) nxge_link_init(nxgep);
2490			(void) nxge_mac_init(nxgep);
2491			(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
2492			RW_EXIT(&nxgep->filter_lock);
2493		}
2494	} else {
2495		cmn_err(CE_WARN, " Last setting will leave nxge%d with "
2496		    " no link capabilities.", instance);
2497		cmn_err(CE_WARN, " Restoring previous setting.");
2498		for (i = param_anar_1000fdx; i < param_anar_asmpause; i++)
2499			param_arr[i].value = param_arr[i].old_value;
2500	}
2501
2502	update_dev = B_FALSE;
2503
2504	if (update_dev) {
2505		RW_ENTER_WRITER(&nxgep->filter_lock);
2506		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2507		    "==> nxge_param_link_update: update dev"));
2508		(void) nxge_rx_mac_disable(nxgep);
2509		(void) nxge_tx_mac_disable(nxgep);
2510		(void) nxge_tx_mac_enable(nxgep);
2511		(void) nxge_rx_mac_enable(nxgep);
2512		RW_EXIT(&nxgep->filter_lock);
2513	}
2514
2515nxge_param_hw_update_exit:
2516	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
2517	    "<== nxge_param_link_update status = 0x%08x", status));
2518	return (status);
2519}
2520
2521/*
2522 * synchronize the  adv* and en* parameters.
2523 *
2524 * See comments in <sys/dld.h> for details of the *_en_*
2525 * parameters.  The usage of ndd for setting adv parameters will
2526 * synchronize all the en parameters with the nxge parameters,
2527 * implicitly disabling any settings made via dladm.
2528 */
2529static void
2530nxge_param_sync(p_nxge_t nxgep)
2531{
2532	p_nxge_param_t	param_arr;
2533	param_arr = nxgep->param_arr;
2534
2535	nxgep->param_en_pause	= param_arr[param_anar_pause].value;
2536	nxgep->param_en_1000fdx	= param_arr[param_anar_1000fdx].value;
2537	nxgep->param_en_100fdx	= param_arr[param_anar_100fdx].value;
2538	nxgep->param_en_10fdx	= param_arr[param_anar_10fdx].value;
2539}
2540
2541/* ARGSUSED */
2542int
2543nxge_dld_get_ip_opt(p_nxge_t nxgep, caddr_t cp)
2544{
2545	uint32_t status, cfg_value;
2546	p_nxge_param_t pa = (p_nxge_param_t)cp;
2547	tcam_class_t class;
2548
2549	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_dld_get_ip_opt"));
2550
2551	/* do the actual hw setup  */
2552	class = nxge_class_name_2value(nxgep, pa->name);
2553	if (class == -1)
2554		return (EINVAL);
2555
2556	cfg_value = 0;
2557	status = nxge_fflp_ip_class_config_get(nxgep, class, &cfg_value);
2558	if (status != NXGE_OK)
2559		return (EINVAL);
2560
2561	/* Filter out the allowed bits */
2562	cfg_value &= (NXGE_CLASS_FLOW_USE_PORTNUM | NXGE_CLASS_FLOW_USE_L2DA |
2563	    NXGE_CLASS_FLOW_USE_VLAN | NXGE_CLASS_FLOW_USE_PROTO |
2564	    NXGE_CLASS_FLOW_USE_IPSRC | NXGE_CLASS_FLOW_USE_IPDST |
2565	    NXGE_CLASS_FLOW_USE_SRC_PORT | NXGE_CLASS_FLOW_USE_DST_PORT);
2566
2567	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2568	    "nxge_param_get_ip_opt_get %x ", cfg_value));
2569
2570	pa->value = cfg_value;
2571
2572	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_ip_opt status "));
2573	return (0);
2574}
2575