xref: /illumos-gate/usr/src/uts/common/io/nxge/nxge_ndd.c (revision 27954b0d964ffcb749cf19296906e7fecdf3da1b)
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 
33 extern 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 
83 int nxge_param_set_mac(p_nxge_t, queue_t *,
84 	mblk_t *, char *, caddr_t);
85 static int nxge_param_set_port_rdc(p_nxge_t, queue_t *,
86 	mblk_t *, char *, caddr_t);
87 static int nxge_param_set_grp_rdc(p_nxge_t, queue_t *,
88 	mblk_t *, char *, caddr_t);
89 static int nxge_param_set_ether_usr(p_nxge_t,
90 	queue_t *, mblk_t *, char *, caddr_t);
91 static int nxge_param_set_ip_usr(p_nxge_t,
92 	queue_t *, mblk_t *, char *, caddr_t);
93 static int nxge_param_set_vlan_rdcgrp(p_nxge_t,
94 	queue_t *, mblk_t *, char *, caddr_t);
95 static int nxge_param_set_mac_rdcgrp(p_nxge_t,
96 	queue_t *, mblk_t *, char *, caddr_t);
97 static int nxge_param_fflp_hash_init(p_nxge_t,
98 	queue_t *, mblk_t *, char *, caddr_t);
99 static int nxge_param_llc_snap_enable(p_nxge_t, queue_t *,
100 	mblk_t *, char *, caddr_t);
101 static int nxge_param_hash_lookup_enable(p_nxge_t, queue_t *,
102 	mblk_t *, char *, caddr_t);
103 static int nxge_param_tcam_enable(p_nxge_t, queue_t *,
104 	mblk_t *, char *, caddr_t);
105 static int nxge_param_get_fw_ver(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
106 static int nxge_param_get_port_mode(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
107 static int nxge_param_get_rxdma_info(p_nxge_t, queue_t *q,
108 	p_mblk_t, caddr_t);
109 static int nxge_param_get_txdma_info(p_nxge_t, queue_t *q,
110 	p_mblk_t, caddr_t);
111 static int nxge_param_get_vlan_rdcgrp(p_nxge_t, queue_t *,
112 	p_mblk_t, caddr_t);
113 static int nxge_param_get_mac_rdcgrp(p_nxge_t, queue_t *,
114 	p_mblk_t, caddr_t);
115 static int nxge_param_get_rxdma_rdcgrp_info(p_nxge_t, queue_t *,
116 	p_mblk_t, caddr_t);
117 static int nxge_param_get_rx_intr_time(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
118 static int nxge_param_get_rx_intr_pkts(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
119 static int nxge_param_get_ip_opt(p_nxge_t, queue_t *, mblk_t *, caddr_t);
120 static int nxge_param_get_mac(p_nxge_t, queue_t *q, p_mblk_t, caddr_t);
121 static int nxge_param_get_debug_flag(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
122 static int nxge_param_set_nxge_debug_flag(p_nxge_t, queue_t *, mblk_t *,
123 	char *, caddr_t);
124 static int nxge_param_set_npi_debug_flag(p_nxge_t,
125 	queue_t *, mblk_t *, char *, caddr_t);
126 static int nxge_param_dump_rdc(p_nxge_t, queue_t *q, p_mblk_t, caddr_t);
127 static int nxge_param_dump_tdc(p_nxge_t, queue_t *q, p_mblk_t, caddr_t);
128 static int nxge_param_dump_mac_regs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
129 static int nxge_param_dump_ipp_regs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
130 static int nxge_param_dump_fflp_regs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
131 static int nxge_param_dump_vlan_table(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
132 static int nxge_param_dump_rdc_table(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
133 static int nxge_param_dump_ptrs(p_nxge_t, queue_t *, p_mblk_t, caddr_t);
134 static 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 
149 static 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 
541 extern void 		*nxge_list;
542 
543 void
544 nxge_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 
635 static int
636 nxge_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 
689 void
690 nxge_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 
734 void
735 nxge_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 
787 void
788 nxge_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 */
842 int
843 nxge_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 */
861 static int
862 nxge_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 */
874 static int
875 nxge_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 */
887 static int
888 nxge_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 */
958 static int
959 nxge_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 */
973 static int
974 nxge_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 */
988 int
989 nxge_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 */
1034 int
1035 nxge_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 */
1103 int
1104 nxge_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 
1194 int
1195 nxge_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 */
1215 int
1216 nxge_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 */
1236 int
1237 nxge_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 */
1247 int
1248 nxge_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 */
1278 int
1279 nxge_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 */
1306 int
1307 nxge_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 */
1334 static int
1335 nxge_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 */
1406 static int
1407 nxge_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 */
1526 static int
1527 nxge_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 */
1598 static int
1599 nxge_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 */
1654 static int
1655 nxge_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 */
1686 static int
1687 nxge_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 */
1718 static int
1719 nxge_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 */
1750 static int
1751 nxge_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 */
1787 static int
1788 nxge_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 */
1821 static int
1822 nxge_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 */
1838 int
1839 nxge_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 */
1884 static int
1885 nxge_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 */
1921 static int
1922 nxge_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 */
1980 static int
1981 nxge_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 */
2041 static int
2042 nxge_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 */
2085 static int
2086 nxge_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 */
2119 static int
2120 nxge_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 */
2138 static int
2139 nxge_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 */
2170 static int
2171 nxge_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 */
2192 static int
2193 nxge_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 */
2211 static int
2212 nxge_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 */
2223 static int
2224 nxge_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 */
2236 static int
2237 nxge_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 */
2248 static int
2249 nxge_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 */
2260 static int
2261 nxge_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 
2275 typedef struct block_info {
2276 	char		*name;
2277 	uint32_t	offset;
2278 } block_info_t;
2279 
2280 block_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 */
2303 static int
2304 nxge_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 */
2409 int
2410 nxge_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 */
2448 int
2449 nxge_get_default(p_nxge_t nxgep, queue_t *q, p_mblk_t mp, caddr_t data)
2450 {
2451 	return (EACCES);
2452 }
2453 
2454 /* ARGSUSED */
2455 int
2456 nxge_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 
2462 boolean_t
2463 nxge_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 
2519 nxge_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  */
2533 static void
2534 nxge_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 */
2546 int
2547 nxge_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