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	uint8_t		ether_class;
1756	uint32_t	status = 0, cfg_value;
1757	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1758	uint8_t		cfg_it = B_FALSE;
1759
1760	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_ether_usr"));
1761
1762	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1763	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1764		return (EINVAL);
1765	}
1766
1767	if (pa->value != cfg_value) {
1768		pa->old_value = pa->value;
1769		pa->value = cfg_value;
1770		cfg_it = B_TRUE;
1771	}
1772
1773	/* do the actual hw setup  */
1774	if (cfg_it == B_TRUE) {
1775		ether_class = mi_strtol(pa->name, &end, 10);
1776#ifdef lint
1777		ether_class = ether_class;
1778#endif
1779		NXGE_DEBUG_MSG((nxgep, NDD_CTL, " nxge_param_set_ether_usr"));
1780	}
1781
1782	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_ether_usr"));
1783	return (status);
1784}
1785
1786/* ARGSUSED */
1787static int
1788nxge_param_set_ip_usr(p_nxge_t nxgep, queue_t *q,
1789	mblk_t *mp, char *value, caddr_t cp)
1790{
1791	char		*end;
1792	tcam_class_t	class;
1793	uint32_t	status, cfg_value;
1794	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1795	uint32_t	cfg_it = B_FALSE;
1796
1797	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_ip_usr"));
1798
1799	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1800	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1801		return (EINVAL);
1802	}
1803
1804	if (pa->value != cfg_value) {
1805		pa->old_value = pa->value;
1806		pa->value = cfg_value;
1807		cfg_it = B_TRUE;
1808	}
1809
1810	/* do the actual hw setup with cfg_value. */
1811	if (cfg_it == B_TRUE) {
1812		class = mi_strtol(pa->name, &end, 10);
1813		status = nxge_fflp_ip_usr_class_config(nxgep, class, pa->value);
1814	}
1815
1816	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_ip_usr"));
1817	return (status);
1818}
1819
1820/* ARGSUSED */
1821static int
1822nxge_class_name_2value(p_nxge_t nxgep, char *name)
1823{
1824	int		i;
1825	int		class_instance = param_class_opt_ip_usr4;
1826	p_nxge_param_t	param_arr;
1827
1828	param_arr = nxgep->param_arr;
1829	for (i = TCAM_CLASS_IP_USER_4; i <= TCAM_CLASS_SCTP_IPV6; i++) {
1830		if (strcmp(param_arr[class_instance].name, name) == 0)
1831			return (i);
1832		class_instance++;
1833	}
1834	return (-1);
1835}
1836
1837/* ARGSUSED */
1838int
1839nxge_param_set_ip_opt(p_nxge_t nxgep, queue_t *q,
1840	mblk_t *mp, char *value, caddr_t cp)
1841{
1842	char		*end;
1843	uint32_t	status, cfg_value;
1844	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1845	tcam_class_t	class;
1846	uint32_t	cfg_it = B_FALSE;
1847
1848	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_ip_opt"));
1849
1850	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1851	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1852		return (EINVAL);
1853	}
1854
1855	if (pa->value != cfg_value) {
1856		pa->old_value = pa->value;
1857		pa->value = cfg_value;
1858		cfg_it = B_TRUE;
1859	}
1860
1861	if (cfg_it == B_TRUE) {
1862		/* do the actual hw setup  */
1863		class = nxge_class_name_2value(nxgep, pa->name);
1864		if (class == -1)
1865			return (EINVAL);
1866
1867		/* Filter out the allowed bits */
1868		pa->value &= (NXGE_CLASS_FLOW_USE_PORTNUM |
1869		    NXGE_CLASS_FLOW_USE_L2DA | NXGE_CLASS_FLOW_USE_VLAN |
1870		    NXGE_CLASS_FLOW_USE_PROTO | NXGE_CLASS_FLOW_USE_IPSRC |
1871		    NXGE_CLASS_FLOW_USE_IPDST | NXGE_CLASS_FLOW_USE_SRC_PORT |
1872		    NXGE_CLASS_FLOW_USE_DST_PORT);
1873
1874		status = nxge_fflp_ip_class_config(nxgep, class, pa->value);
1875		if (status != NXGE_OK)
1876			return (EINVAL);
1877	}
1878
1879	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_ip_opt"));
1880	return (0);
1881}
1882
1883/* ARGSUSED */
1884static int
1885nxge_param_get_ip_opt(p_nxge_t nxgep, queue_t *q,
1886	mblk_t *mp, caddr_t cp)
1887{
1888	uint32_t status, cfg_value;
1889	p_nxge_param_t pa = (p_nxge_param_t)cp;
1890	tcam_class_t class;
1891
1892	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_ip_opt"));
1893
1894	/* do the actual hw setup  */
1895	class = nxge_class_name_2value(nxgep, pa->name);
1896	if (class == -1)
1897		return (EINVAL);
1898
1899	cfg_value = 0;
1900	status = nxge_fflp_ip_class_config_get(nxgep, class, &cfg_value);
1901	if (status != NXGE_OK)
1902		return (EINVAL);
1903
1904	/* Filter out the allowed bits */
1905	cfg_value &= (NXGE_CLASS_FLOW_USE_PORTNUM | NXGE_CLASS_FLOW_USE_L2DA |
1906	    NXGE_CLASS_FLOW_USE_VLAN | NXGE_CLASS_FLOW_USE_PROTO |
1907	    NXGE_CLASS_FLOW_USE_IPSRC | NXGE_CLASS_FLOW_USE_IPDST |
1908	    NXGE_CLASS_FLOW_USE_SRC_PORT | NXGE_CLASS_FLOW_USE_DST_PORT);
1909
1910	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1911	    "nxge_param_get_ip_opt_get %x ", cfg_value));
1912
1913	pa->value = cfg_value;
1914	(void) mi_mpprintf(mp, "%x", cfg_value);
1915
1916	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_ip_opt status "));
1917	return (0);
1918}
1919
1920/* ARGSUSED */
1921static int
1922nxge_param_fflp_hash_init(p_nxge_t nxgep, queue_t *q,
1923	mblk_t *mp, char *value, caddr_t cp)
1924{
1925	char		*end;
1926	uint32_t	status, cfg_value;
1927	p_nxge_param_t	pa = (p_nxge_param_t)cp;
1928	tcam_class_t	class;
1929	uint32_t	cfg_it = B_FALSE;
1930
1931	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_fflp_hash_init"));
1932
1933	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_HEX);
1934	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
1935		return (EINVAL);
1936	}
1937
1938	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1939	    "nxge_param_fflp_hash_init value %x", cfg_value));
1940
1941	if (pa->value != cfg_value) {
1942		pa->old_value = pa->value;
1943		pa->value = cfg_value;
1944		cfg_it = B_TRUE;
1945	}
1946
1947	if (cfg_it == B_TRUE) {
1948		char *h_name;
1949
1950		/* do the actual hw setup */
1951		h_name = pa->name;
1952		h_name++;
1953		class = mi_strtol(h_name, &end, 10);
1954		switch (class) {
1955			case 1:
1956				status = nxge_fflp_set_hash1(nxgep,
1957				    (uint32_t)pa->value);
1958				break;
1959			case 2:
1960				status = nxge_fflp_set_hash2(nxgep,
1961				    (uint16_t)pa->value);
1962				break;
1963
1964			default:
1965			NXGE_DEBUG_MSG((nxgep, NDD_CTL,
1966			    " nxge_param_fflp_hash_init"
1967			    " %s Wrong hash var %d",
1968			    pa->name, class));
1969			return (EINVAL);
1970		}
1971		if (status != NXGE_OK)
1972			return (EINVAL);
1973	}
1974
1975	NXGE_DEBUG_MSG((nxgep, NDD_CTL, " <== nxge_param_fflp_hash_init"));
1976	return (0);
1977}
1978
1979/* ARGSUSED */
1980static int
1981nxge_param_set_grp_rdc(p_nxge_t nxgep, queue_t *q,
1982	mblk_t *mp, char *value, caddr_t cp)
1983{
1984	char			*end;
1985	uint32_t		status = 0, cfg_value;
1986	p_nxge_param_t		pa = (p_nxge_param_t)cp;
1987	uint32_t		cfg_it = B_FALSE;
1988	int			rdc_grp;
1989	uint8_t			real_rdc;
1990	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
1991	p_nxge_hw_pt_cfg_t	p_cfgp;
1992	p_nxge_rdc_grp_t	rdc_grp_p;
1993
1994	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
1995	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
1996
1997	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_grp_rdc"));
1998
1999	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
2000	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2001		return (EINVAL);
2002	}
2003
2004	if (cfg_value >= p_cfgp->max_rdcs) {
2005		return (EINVAL);
2006	}
2007
2008	if (pa->value != cfg_value) {
2009		pa->old_value = pa->value;
2010		pa->value = cfg_value;
2011		cfg_it = B_TRUE;
2012	}
2013
2014	if (cfg_it == B_TRUE) {
2015		char *grp_name;
2016		grp_name = pa->name;
2017		grp_name += strlen("default-grp");
2018		rdc_grp = mi_strtol(grp_name, &end, 10);
2019		rdc_grp_p = &p_dma_cfgp->rdc_grps[rdc_grp];
2020		real_rdc = rdc_grp_p->start_rdc + cfg_value;
2021		if (nxge_check_rxdma_rdcgrp_member(nxgep, rdc_grp,
2022		    cfg_value) == B_FALSE) {
2023			pa->value = pa->old_value;
2024			NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2025			    " nxge_param_set_grp_rdc"
2026			    " %d read %d actual %d outof range",
2027			    rdc_grp, cfg_value, real_rdc));
2028			return (EINVAL);
2029		}
2030		status = nxge_rxdma_cfg_rdcgrp_default_rdc(nxgep, rdc_grp,
2031		    real_rdc);
2032		if (status != NXGE_OK)
2033			return (EINVAL);
2034	}
2035
2036	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_grp_rdc"));
2037	return (0);
2038}
2039
2040/* ARGSUSED */
2041static int
2042nxge_param_set_port_rdc(p_nxge_t nxgep, queue_t *q,
2043	mblk_t *mp, char *value, caddr_t cp)
2044{
2045	char		*end;
2046	uint32_t	status = B_TRUE, cfg_value;
2047	p_nxge_param_t	pa = (p_nxge_param_t)cp;
2048	uint32_t	cfg_it = B_FALSE;
2049
2050	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
2051	p_nxge_hw_pt_cfg_t	p_cfgp;
2052
2053	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_port_rdc"));
2054	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
2055	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
2056
2057	cfg_value = (uint32_t)mi_strtol(value, &end, BASE_ANY);
2058	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2059		return (EINVAL);
2060	}
2061
2062	if (pa->value != cfg_value) {
2063		if (cfg_value >= p_cfgp->max_rdcs)
2064			return (EINVAL);
2065		pa->old_value = pa->value;
2066		pa->value = cfg_value;
2067		cfg_it = B_TRUE;
2068	}
2069
2070	if (cfg_it == B_TRUE) {
2071		int rdc;
2072		if ((rdc = nxge_dci_map(nxgep, VP_BOUND_RX, cfg_value)) < 0)
2073			return (EINVAL);
2074		status = nxge_rxdma_cfg_port_default_rdc(nxgep,
2075		    nxgep->function_num, rdc);
2076		if (status != NXGE_OK)
2077			return (EINVAL);
2078	}
2079
2080	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_port_rdc"));
2081	return (0);
2082}
2083
2084/* ARGSUSED */
2085static int
2086nxge_param_set_nxge_debug_flag(p_nxge_t nxgep, queue_t *q,
2087	mblk_t *mp, char *value, caddr_t cp)
2088{
2089	char *end;
2090	uint32_t status = 0;
2091	uint64_t cfg_value = 0;
2092	p_nxge_param_t pa = (p_nxge_param_t)cp;
2093	uint32_t cfg_it = B_FALSE;
2094
2095	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_nxge_debug_flag"));
2096	cfg_value = mi_strtol(value, &end, BASE_HEX);
2097
2098	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2099		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2100		    " nxge_param_set_nxge_debug_flag"
2101		    " outof range %llx", cfg_value));
2102		return (EINVAL);
2103	}
2104	if (pa->value != cfg_value) {
2105		pa->old_value = pa->value;
2106		pa->value = cfg_value;
2107		cfg_it = B_TRUE;
2108	}
2109
2110	if (cfg_it == B_TRUE) {
2111		nxgep->nxge_debug_level = pa->value;
2112	}
2113
2114	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_nxge_debug_flag"));
2115	return (status);
2116}
2117
2118/* ARGSUSED */
2119static int
2120nxge_param_get_debug_flag(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2121{
2122	int		status = 0;
2123	p_nxge_param_t	pa = (p_nxge_param_t)cp;
2124
2125	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_get_debug_flag"));
2126
2127	if (pa->value > 0xffffffff)
2128		(void) mi_mpprintf(mp, "%x%x",  (int)(pa->value >> 32),
2129		    (int)(pa->value & 0xffffffff));
2130	else
2131		(void) mi_mpprintf(mp, "%x", (int)pa->value);
2132
2133	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_debug_flag"));
2134	return (status);
2135}
2136
2137/* ARGSUSED */
2138static int
2139nxge_param_set_npi_debug_flag(p_nxge_t nxgep, queue_t *q,
2140	mblk_t *mp, char *value, caddr_t cp)
2141{
2142	char		*end;
2143	uint32_t	status = 0;
2144	uint64_t	 cfg_value = 0;
2145	p_nxge_param_t	pa;
2146	uint32_t	cfg_it = B_FALSE;
2147
2148	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_set_npi_debug_flag"));
2149	cfg_value = mi_strtol(value, &end, BASE_HEX);
2150	pa = (p_nxge_param_t)cp;
2151	if (PARAM_OUTOF_RANGE(value, end, cfg_value, pa)) {
2152		NXGE_DEBUG_MSG((nxgep, NDD_CTL, " nxge_param_set_npi_debug_flag"
2153		    " outof range %llx", cfg_value));
2154		return (EINVAL);
2155	}
2156	if (pa->value != cfg_value) {
2157		pa->old_value = pa->value;
2158		pa->value = cfg_value;
2159		cfg_it = B_TRUE;
2160	}
2161
2162	if (cfg_it == B_TRUE) {
2163		npi_debug_level = pa->value;
2164	}
2165	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_set_debug_flag"));
2166	return (status);
2167}
2168
2169/* ARGSUSED */
2170static int
2171nxge_param_dump_rdc(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2172{
2173	nxge_grp_set_t *set = &nxgep->rx_set;
2174	int rdc;
2175
2176	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_rdc"));
2177
2178	if (!isLDOMguest(nxgep))
2179		(void) npi_rxdma_dump_fzc_regs(NXGE_DEV_NPI_HANDLE(nxgep));
2180
2181	for (rdc = 0; rdc < NXGE_MAX_TDCS; rdc++) {
2182		if ((1 << rdc) & set->owned.map) {
2183			(void) nxge_dump_rxdma_channel(nxgep, rdc);
2184		}
2185	}
2186
2187	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_rdc"));
2188	return (0);
2189}
2190
2191/* ARGSUSED */
2192static int
2193nxge_param_dump_tdc(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2194{
2195	nxge_grp_set_t *set = &nxgep->tx_set;
2196	int tdc;
2197
2198	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_tdc"));
2199
2200	for (tdc = 0; tdc < NXGE_MAX_TDCS; tdc++) {
2201		if ((1 << tdc) & set->owned.map) {
2202			(void) nxge_txdma_regs_dump(nxgep, tdc);
2203		}
2204	}
2205
2206	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_tdc"));
2207	return (0);
2208}
2209
2210/* ARGSUSED */
2211static int
2212nxge_param_dump_fflp_regs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2213{
2214	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_fflp_regs"));
2215
2216	(void) npi_fflp_dump_regs(NXGE_DEV_NPI_HANDLE(nxgep));
2217
2218	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_fflp_regs"));
2219	return (0);
2220}
2221
2222/* ARGSUSED */
2223static int
2224nxge_param_dump_mac_regs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2225{
2226	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_mac_regs"));
2227
2228	(void) npi_mac_dump_regs(NXGE_DEV_NPI_HANDLE(nxgep),
2229	    nxgep->function_num);
2230
2231	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_mac_regs"));
2232	return (0);
2233}
2234
2235/* ARGSUSED */
2236static int
2237nxge_param_dump_ipp_regs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2238{
2239	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "==> nxge_param_dump_ipp_regs"));
2240
2241	(void) npi_ipp_dump_regs(NXGE_DEV_NPI_HANDLE(nxgep),
2242	    nxgep->function_num);
2243	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_ipp_regs"));
2244	return (0);
2245}
2246
2247/* ARGSUSED */
2248static int
2249nxge_param_dump_vlan_table(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2250{
2251	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_dump_vlan_table"));
2252
2253	(void) npi_fflp_vlan_tbl_dump(NXGE_DEV_NPI_HANDLE(nxgep));
2254
2255	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_dump_vlan_table"));
2256	return (0);
2257}
2258
2259/* ARGSUSED */
2260static int
2261nxge_param_dump_rdc_table(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2262{
2263	uint8_t	table;
2264
2265	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_dump_rdc_table"));
2266	for (table = 0; table < NXGE_MAX_RDC_GROUPS; table++) {
2267		(void) npi_rxdma_dump_rdc_table(NXGE_DEV_NPI_HANDLE(nxgep),
2268		    table);
2269	}
2270
2271	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_dump_rdc_table"));
2272	return (0);
2273}
2274
2275typedef struct block_info {
2276	char		*name;
2277	uint32_t	offset;
2278} block_info_t;
2279
2280block_info_t reg_block[] = {
2281	{"PIO",		PIO},
2282	{"FZC_PIO",	FZC_PIO},
2283	{"FZC_XMAC",	FZC_MAC},
2284	{"FZC_IPP",	FZC_IPP},
2285	{"FFLP",	FFLP},
2286	{"FZC_FFLP",	FZC_FFLP},
2287	{"PIO_VADDR",	PIO_VADDR},
2288	{"ZCP",	ZCP},
2289	{"FZC_ZCP",	FZC_ZCP},
2290	{"DMC",	DMC},
2291	{"FZC_DMC",	FZC_DMC},
2292	{"TXC",	TXC},
2293	{"FZC_TXC",	FZC_TXC},
2294	{"PIO_LDSV",	PIO_LDSV},
2295	{"PIO_LDGIM",	PIO_LDGIM},
2296	{"PIO_IMASK0",	PIO_IMASK0},
2297	{"PIO_IMASK1",	PIO_IMASK1},
2298	{"FZC_PROM",	FZC_PROM},
2299	{"END",	ALL_FF_32},
2300};
2301
2302/* ARGSUSED */
2303static int
2304nxge_param_dump_ptrs(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t cp)
2305{
2306	uint_t			print_len, buf_len;
2307	p_mblk_t		np;
2308	int			rdc, tdc, block;
2309	uint64_t		base;
2310	p_nxge_dma_pt_cfg_t	p_dma_cfgp;
2311	p_nxge_hw_pt_cfg_t	p_cfgp;
2312	int			buff_alloc_size = NXGE_NDD_INFODUMP_BUFF_8K;
2313	p_tx_ring_t 		*tx_rings;
2314	p_rx_rcr_rings_t 	rx_rcr_rings;
2315	p_rx_rcr_ring_t		*rcr_rings;
2316	p_rx_rbr_rings_t 	rx_rbr_rings;
2317	p_rx_rbr_ring_t		*rbr_rings;
2318
2319	NXGE_DEBUG_MSG((nxgep, IOC_CTL,
2320	    "==> nxge_param_dump_ptrs"));
2321
2322	(void) mi_mpprintf(mp, "ptr information for Port\t %d \n",
2323	    nxgep->function_num);
2324
2325	if ((np = allocb(buff_alloc_size, BPRI_HI)) == NULL) {
2326		/* The following may work even if we cannot get a large buf. */
2327		(void) mi_mpprintf(mp, "%s\n", "out of buffer");
2328		return (0);
2329	}
2330
2331	buf_len = buff_alloc_size;
2332	mp->b_cont = np;
2333	p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config;
2334	p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config;
2335
2336	rx_rcr_rings = nxgep->rx_rcr_rings;
2337	rcr_rings = rx_rcr_rings->rcr_rings;
2338	rx_rbr_rings = nxgep->rx_rbr_rings;
2339	rbr_rings = rx_rbr_rings->rbr_rings;
2340	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2341	    "nxgep (nxge_t) $%p\n"
2342	    "dev_regs (dev_regs_t) $%p\n",
2343	    (void *)nxgep, (void *)nxgep->dev_regs);
2344
2345	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2346
2347	/* do register pointers */
2348	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2349	    "reg base (npi_reg_ptr_t) $%p\t "
2350	    "pci reg (npi_reg_ptr_t) $%p\n",
2351	    (void *)nxgep->dev_regs->nxge_regp,
2352	    (void *)nxgep->dev_regs->nxge_pciregp);
2353
2354	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2355
2356	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2357	    "\nBlock \t Offset \n");
2358
2359	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2360	block = 0;
2361#if defined(__i386)
2362	base = (uint64_t)(uint32_t)nxgep->dev_regs->nxge_regp;
2363#else
2364	base = (uint64_t)nxgep->dev_regs->nxge_regp;
2365#endif
2366	while (reg_block[block].offset != ALL_FF_32) {
2367		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2368		    "%9s\t 0x%llx\n",
2369		    reg_block[block].name,
2370		    (unsigned long long)(reg_block[block].offset + base));
2371		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2372		block++;
2373	}
2374
2375	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2376	    "\nRDC\t rcrp (rx_rcr_ring_t)\t "
2377	    "rbrp (rx_rbr_ring_t)\n");
2378
2379	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2380
2381	for (rdc = 0; rdc < p_cfgp->max_rdcs; rdc++) {
2382		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2383		    " %d\t  $%p\t\t   $%p\n",
2384		    rdc, (void *)rcr_rings[rdc],
2385		    (void *)rbr_rings[rdc]);
2386		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2387	}
2388
2389	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2390	    "\nTDC\t tdcp (tx_ring_t)\n");
2391
2392	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2393	tx_rings = nxgep->tx_rings->rings;
2394	for (tdc = 0; tdc < p_cfgp->tdc.count; tdc++) {
2395		print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len,
2396		    " %d\t  $%p\n", tdc, (void *)tx_rings[tdc]);
2397		ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2398	}
2399
2400	print_len = snprintf((char *)((mblk_t *)np)->b_wptr, buf_len, "\n\n");
2401
2402	ADVANCE_PRINT_BUFFER(np, print_len, buf_len);
2403	NXGE_DEBUG_MSG((nxgep, IOC_CTL, "<== nxge_param_dump_ptrs"));
2404	return (0);
2405}
2406
2407
2408/* ARGSUSED */
2409int
2410nxge_nd_get_names(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t param)
2411{
2412	ND		*nd;
2413	NDE		*nde;
2414	char		*rwtag;
2415	boolean_t	get_ok, set_ok;
2416	size_t		param_len;
2417	int		status = 0;
2418
2419	nd = (ND *)param;
2420	if (!nd)
2421		return (ENOENT);
2422
2423	for (nde = nd->nd_tbl; nde->nde_name; nde++) {
2424		get_ok = (nde->nde_get_pfi != nxge_get_default) &&
2425		    (nde->nde_get_pfi != NULL);
2426		set_ok = (nde->nde_set_pfi != nxge_set_default) &&
2427		    (nde->nde_set_pfi != NULL);
2428		if (get_ok) {
2429			if (set_ok)
2430				rwtag = "read and write";
2431			else
2432				rwtag = "read only";
2433		} else if (set_ok)
2434			rwtag = "write only";
2435		else {
2436			continue;
2437		}
2438		param_len = strlen(rwtag);
2439		param_len += strlen(nde->nde_name);
2440		param_len += 4;
2441
2442		(void) mi_mpprintf(mp, "%s (%s)", nde->nde_name, rwtag);
2443	}
2444	return (status);
2445}
2446
2447/* ARGSUSED */
2448int
2449nxge_get_default(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t data)
2450{
2451	return (EACCES);
2452}
2453
2454/* ARGSUSED */
2455int
2456nxge_set_default(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, char *value,
2457	caddr_t data)
2458{
2459	return (EACCES);
2460}
2461
2462boolean_t
2463nxge_param_link_update(p_nxge_t nxgep)
2464{
2465	p_nxge_param_t 		param_arr;
2466	nxge_param_index_t 	i;
2467	boolean_t 		update_xcvr;
2468	boolean_t 		update_dev;
2469	int 			instance;
2470	boolean_t 		status = B_TRUE;
2471
2472	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_param_link_update"));
2473
2474	param_arr = nxgep->param_arr;
2475	instance = nxgep->instance;
2476	update_xcvr = B_FALSE;
2477	for (i = param_anar_1000fdx; i < param_anar_asmpause; i++) {
2478		update_xcvr |= param_arr[i].value;
2479	}
2480
2481	if (update_xcvr) {
2482		update_xcvr = B_FALSE;
2483		for (i = param_autoneg; i < param_enable_ipg0; i++) {
2484			update_xcvr |=
2485			    (param_arr[i].value != param_arr[i].old_value);
2486			param_arr[i].old_value = param_arr[i].value;
2487		}
2488		if (update_xcvr) {
2489			NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2490			    "==> nxge_param_link_update: update xcvr"));
2491			RW_ENTER_WRITER(&nxgep->filter_lock);
2492			(void) nxge_link_monitor(nxgep, LINK_MONITOR_STOP);
2493			(void) nxge_link_init(nxgep);
2494			(void) nxge_mac_init(nxgep);
2495			(void) nxge_link_monitor(nxgep, LINK_MONITOR_START);
2496			RW_EXIT(&nxgep->filter_lock);
2497		}
2498	} else {
2499		cmn_err(CE_WARN, " Last setting will leave nxge%d with "
2500		    " no link capabilities.", instance);
2501		cmn_err(CE_WARN, " Restoring previous setting.");
2502		for (i = param_anar_1000fdx; i < param_anar_asmpause; i++)
2503			param_arr[i].value = param_arr[i].old_value;
2504	}
2505
2506	update_dev = B_FALSE;
2507
2508	if (update_dev) {
2509		RW_ENTER_WRITER(&nxgep->filter_lock);
2510		NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2511		    "==> nxge_param_link_update: update dev"));
2512		(void) nxge_rx_mac_disable(nxgep);
2513		(void) nxge_tx_mac_disable(nxgep);
2514		(void) nxge_tx_mac_enable(nxgep);
2515		(void) nxge_rx_mac_enable(nxgep);
2516		RW_EXIT(&nxgep->filter_lock);
2517	}
2518
2519nxge_param_hw_update_exit:
2520	NXGE_DEBUG_MSG((nxgep, DDI_CTL,
2521	    "<== nxge_param_link_update status = 0x%08x", status));
2522	return (status);
2523}
2524
2525/*
2526 * synchronize the  adv* and en* parameters.
2527 *
2528 * See comments in <sys/dld.h> for details of the *_en_*
2529 * parameters.  The usage of ndd for setting adv parameters will
2530 * synchronize all the en parameters with the nxge parameters,
2531 * implicitly disabling any settings made via dladm.
2532 */
2533static void
2534nxge_param_sync(p_nxge_t nxgep)
2535{
2536	p_nxge_param_t	param_arr;
2537	param_arr = nxgep->param_arr;
2538
2539	nxgep->param_en_pause	= param_arr[param_anar_pause].value;
2540	nxgep->param_en_1000fdx	= param_arr[param_anar_1000fdx].value;
2541	nxgep->param_en_100fdx	= param_arr[param_anar_100fdx].value;
2542	nxgep->param_en_10fdx	= param_arr[param_anar_10fdx].value;
2543}
2544
2545/* ARGSUSED */
2546int
2547nxge_dld_get_ip_opt(p_nxge_t nxgep, caddr_t cp)
2548{
2549	uint32_t status, cfg_value;
2550	p_nxge_param_t pa = (p_nxge_param_t)cp;
2551	tcam_class_t class;
2552
2553	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "==> nxge_dld_get_ip_opt"));
2554
2555	/* do the actual hw setup  */
2556	class = nxge_class_name_2value(nxgep, pa->name);
2557	if (class == -1)
2558		return (EINVAL);
2559
2560	cfg_value = 0;
2561	status = nxge_fflp_ip_class_config_get(nxgep, class, &cfg_value);
2562	if (status != NXGE_OK)
2563		return (EINVAL);
2564
2565	/* Filter out the allowed bits */
2566	cfg_value &= (NXGE_CLASS_FLOW_USE_PORTNUM | NXGE_CLASS_FLOW_USE_L2DA |
2567	    NXGE_CLASS_FLOW_USE_VLAN | NXGE_CLASS_FLOW_USE_PROTO |
2568	    NXGE_CLASS_FLOW_USE_IPSRC | NXGE_CLASS_FLOW_USE_IPDST |
2569	    NXGE_CLASS_FLOW_USE_SRC_PORT | NXGE_CLASS_FLOW_USE_DST_PORT);
2570
2571	NXGE_DEBUG_MSG((nxgep, NDD_CTL,
2572	    "nxge_param_get_ip_opt_get %x ", cfg_value));
2573
2574	pa->value = cfg_value;
2575
2576	NXGE_DEBUG_MSG((nxgep, NDD_CTL, "<== nxge_param_get_ip_opt status "));
2577	return (0);
2578}
2579