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