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