xref: /illumos-gate/usr/src/uts/common/io/nxge/npi/npi_vir.c (revision 533affcbc7fc4d0c8132976ea454aaa715fe2307)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <npi_vir.h>
27 
28 /* One register only */
29 uint64_t pio_offset[] = {
30 	DEV_FUNC_SR_REG
31 };
32 
33 const char *pio_name[] = {
34 	"DEV_FUNC_SR_REG",
35 };
36 
37 /* One register only */
38 uint64_t fzc_pio_offset[] = {
39 	MULTI_PART_CTL_REG,
40 	LDGITMRES_REG
41 };
42 
43 const char *fzc_pio_name[] = {
44 	"MULTI_PART_CTL_REG",
45 	"LDGITMRES_REG"
46 };
47 
48 /* 64 sets */
49 uint64_t fzc_pio_dma_bind_offset[] = {
50 	DMA_BIND_REG
51 };
52 
53 const char *fzc_pio_dma_bind_name[] = {
54 	"DMA_BIND_REG",
55 };
56 
57 /* 69 logical devices */
58 uint64_t fzc_pio_ldgnum_offset[] = {
59 	LDG_NUM_REG
60 };
61 
62 const char *fzc_pio_ldgnum_name[] = {
63 	"LDG_NUM_REG",
64 };
65 
66 /* PIO_LDSV, 64 sets by 8192 bytes */
67 uint64_t pio_ldsv_offset[] = {
68 	LDSV0_REG,
69 	LDSV1_REG,
70 	LDSV2_REG,
71 	LDGIMGN_REG
72 };
73 const char *pio_ldsv_name[] = {
74 	"LDSV0_REG",
75 	"LDSV1_REG",
76 	"LDSV2_REG",
77 	"LDGIMGN_REG"
78 };
79 
80 /* PIO_IMASK0: 64 by 8192 */
81 uint64_t pio_imask0_offset[] = {
82 	LD_IM0_REG,
83 };
84 
85 const char *pio_imask0_name[] = {
86 	"LD_IM0_REG",
87 };
88 
89 /* PIO_IMASK1: 5 by 8192 */
90 uint64_t pio_imask1_offset[] = {
91 	LD_IM1_REG
92 };
93 
94 const char *pio_imask1_name[] = {
95 	"LD_IM1_REG"
96 };
97 
98 /* SID: 64 by 8 */
99 uint64_t fzc_pio_sid_offset[] = {
100 	SID_REG
101 };
102 
103 const char *fzc_pio_sid_name[] = {
104 	"SID_REG"
105 };
106 
107 npi_status_t
108 npi_vir_dump_pio_fzc_regs_one(npi_handle_t handle)
109 {
110 	uint64_t value;
111 	int num_regs, i;
112 
113 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
114 	    "\nPIO FZC Common Register Dump\n"));
115 
116 	num_regs = sizeof (pio_offset) / sizeof (uint64_t);
117 	for (i = 0; i < num_regs; i++) {
118 		value = 0;
119 		NXGE_REG_RD64(handle, pio_offset[i], &value);
120 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
121 		    "%s\t 0x%08llx \n",
122 		    pio_offset[i],
123 		    pio_name[i], value));
124 	}
125 
126 	num_regs = sizeof (fzc_pio_offset) / sizeof (uint64_t);
127 	for (i = 0; i < num_regs; i++) {
128 		NXGE_REG_RD64(handle, fzc_pio_offset[i], &value);
129 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
130 		    "%s\t 0x%08llx \n",
131 		    fzc_pio_offset[i],
132 		    fzc_pio_name[i], value));
133 	}
134 
135 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
136 	    "\n PIO FZC Register Dump Done \n"));
137 	return (NPI_SUCCESS);
138 }
139 
140 npi_status_t
141 npi_vir_dump_ldgnum(npi_handle_t handle)
142 {
143 	uint64_t value = 0, offset = 0;
144 	int num_regs, i, ldv;
145 
146 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
147 	    "\nFZC PIO LDG Number Register Dump\n"));
148 
149 	num_regs = sizeof (fzc_pio_ldgnum_offset) / sizeof (uint64_t);
150 	for (ldv = 0; ldv < NXGE_INT_MAX_LDS; ldv++) {
151 		for (i = 0; i < num_regs; i++) {
152 			value = 0;
153 			offset = fzc_pio_ldgnum_offset[i] + 8 * ldv;
154 			NXGE_REG_RD64(handle, offset, &value);
155 			NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
156 			    "Logical Device %d: 0x%08llx "
157 			    "%s\t %d\n",
158 			    ldv, offset,
159 			    fzc_pio_ldgnum_name[i], value));
160 		}
161 	}
162 
163 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
164 	    "\n FZC PIO LDG Register Dump Done \n"));
165 
166 	return (NPI_SUCCESS);
167 }
168 
169 npi_status_t
170 npi_vir_dump_ldsv(npi_handle_t handle)
171 {
172 	uint64_t value, offset;
173 	int num_regs, i, ldg;
174 
175 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
176 	    "\nLD Device State Vector Register Dump\n"));
177 
178 	num_regs = sizeof (pio_ldsv_offset) / sizeof (uint64_t);
179 	for (ldg = 0; ldg < NXGE_INT_MAX_LDGS; ldg++) {
180 		for (i = 0; i < num_regs; i++) {
181 			value = 0;
182 			offset = pio_ldsv_offset[i] + 8192 * ldg;
183 			NXGE_REG_RD64(handle, offset, &value);
184 			NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
185 			    "LDG State: group %d: 0x%08llx "
186 			    "%s\t 0x%08llx \n",
187 			    ldg, offset,
188 			    pio_ldsv_name[i], value));
189 		}
190 	}
191 
192 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
193 	    "\n FZC PIO LDG Register Dump Done \n"));
194 
195 	return (NPI_SUCCESS);
196 }
197 
198 npi_status_t
199 npi_vir_dump_imask0(npi_handle_t handle)
200 {
201 	uint64_t value, offset;
202 	int num_regs, i, ldv;
203 
204 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
205 	    "\nLD Interrupt Mask Register Dump\n"));
206 
207 	num_regs = sizeof (pio_imask0_offset) / sizeof (uint64_t);
208 	for (ldv = 0; ldv < 64; ldv++) {
209 		for (i = 0; i < num_regs; i++) {
210 			value = 0;
211 			offset = pio_imask0_offset[i] + 8192 * ldv;
212 			NXGE_REG_RD64(handle, offset,
213 			    &value);
214 			NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
215 			    "LD Interrupt Mask %d: 0x%08llx "
216 			    "%s\t 0x%08llx \n",
217 			    ldv, offset,
218 			    pio_imask0_name[i], value));
219 		}
220 	}
221 	num_regs = sizeof (pio_imask1_offset) / sizeof (uint64_t);
222 	for (ldv = 64; ldv < 69; ldv++) {
223 		for (i = 0; i < num_regs; i++) {
224 			value = 0;
225 			offset = pio_imask1_offset[i] + 8192 * (ldv - 64);
226 			NXGE_REG_RD64(handle, offset,
227 			    &value);
228 			NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
229 			    "LD Interrupt Mask %d: 0x%08llx "
230 			    "%s\t 0x%08llx \n",
231 			    ldv, offset,
232 			    pio_imask1_name[i], value));
233 		}
234 	}
235 
236 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
237 	    "\n FZC PIO Logical Device Group Register Dump Done \n"));
238 
239 	return (NPI_SUCCESS);
240 }
241 
242 npi_status_t
243 npi_vir_dump_sid(npi_handle_t handle)
244 {
245 	uint64_t value, offset;
246 	int num_regs, i, ldg;
247 
248 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
249 	    "\nSystem Interrupt Data Register Dump\n"));
250 
251 	num_regs = sizeof (fzc_pio_sid_offset) / sizeof (uint64_t);
252 	for (ldg = 0; ldg < NXGE_INT_MAX_LDGS; ldg++) {
253 		for (i = 0; i < num_regs; i++) {
254 			value = 0;
255 			offset = fzc_pio_sid_offset[i] + 8 * ldg;
256 			NXGE_REG_RD64(handle, offset,
257 			    &value);
258 			NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
259 			    "SID for group %d: 0x%08llx "
260 			    "%s\t 0x%08llx \n",
261 			    ldg, offset,
262 			    fzc_pio_sid_name[i], value));
263 		}
264 	}
265 
266 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
267 	    "\n FZC PIO SID Register Dump Done \n"));
268 
269 	return (NPI_SUCCESS);
270 }
271 
272 /*
273  * npi_dev_func_sr_init():
274  *	This function is called to initialize the device function
275  *	shared register (set the software implementation lock
276  *	state to FREE).
277  * Parameters:
278  *	handle		- NPI handle
279  * Return:
280  *	NPI_SUCCESS	- If initialization is complete successfully.
281  *			  (set sr bits to free).
282  *	Error:
283  *	NPI_FAILURE
284  *		VIR_TAS_BUSY
285  */
286 
287 npi_status_t
288 npi_dev_func_sr_init(npi_handle_t handle)
289 {
290 	dev_func_sr_t		sr;
291 	int			status = NPI_SUCCESS;
292 
293 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
294 	if (!sr.bits.ldw.tas) {
295 		/*
296 		 * After read, this bit is set to 1 by hardware.
297 		 * We own it if tas bit read as 0.
298 		 * Set the lock state to free if it is in reset state.
299 		 */
300 		if (!sr.bits.ldw.sr) {
301 			/* reset state */
302 			sr.bits.ldw.sr |= NPI_DEV_SR_LOCK_ST_FREE;
303 			NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
304 			sr.bits.ldw.tas = 0;
305 			NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
306 		}
307 
308 		NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
309 		    " npi_dev_func_sr_init"
310 		    " sr <0x%x>",
311 		    sr.bits.ldw.sr));
312 	} else {
313 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
314 		    " npi_dev_func_sr_init"
315 		    " tas busy <0x%x>",
316 		    sr.bits.ldw));
317 		status = NPI_VIR_TAS_BUSY(sr.bits.ldw.funcid);
318 	}
319 
320 	return (status);
321 }
322 
323 /*
324  * npi_dev_func_sr_lock_enter():
325  *	This function is called to lock the function shared register
326  *	by setting the lock state to busy.
327  * Parameters:
328  *	handle		- NPI handle
329  * Return:
330  *	NPI_SUCCESS	- If the function id can own the lock.
331  *
332  *	Error:
333  *	NPI_FAILURE
334  *		VIR_SR_RESET
335  *		VIR_SR_BUSY
336  *		VIR_SR_INVALID
337  *		VIR_TAS_BUSY
338  */
339 
340 npi_status_t
341 npi_dev_func_sr_lock_enter(npi_handle_t handle)
342 {
343 	dev_func_sr_t		sr;
344 	int			status = NPI_SUCCESS;
345 	uint32_t		state;
346 
347 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
348 	if (!sr.bits.ldw.tas) {
349 		/*
350 		 * tas bit will be set to 1 by hardware.
351 		 * reset tas bit when we unlock the sr.
352 		 */
353 		state = sr.bits.ldw.sr & NPI_DEV_SR_LOCK_ST_MASK;
354 		switch (state) {
355 		case NPI_DEV_SR_LOCK_ST_FREE:
356 			/*
357 			 * set it to busy and our function id.
358 			 */
359 			sr.bits.ldw.sr |= (NPI_DEV_SR_LOCK_ST_BUSY |
360 			    (sr.bits.ldw.funcid <<
361 			    NPI_DEV_SR_LOCK_FID_SHIFT));
362 			NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
363 			break;
364 
365 		case NPI_DEV_SR_LOCK_ST_RESET:
366 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
367 			    " npi_dev_func_sr_lock_enter"
368 			    " reset state <0x%x>",
369 			    sr.bits.ldw.sr));
370 			status = NPI_VIR_SR_RESET(sr.bits.ldw.funcid);
371 			break;
372 
373 		case NPI_DEV_SR_LOCK_ST_BUSY:
374 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
375 			    " npi_dev_func_sr_lock_enter"
376 			    " busy <0x%x>",
377 			    sr.bits.ldw.sr));
378 			status = NPI_VIR_SR_BUSY(sr.bits.ldw.funcid);
379 			break;
380 
381 		default:
382 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
383 			    " npi_dev_func_sr_lock_enter",
384 			    " invalid state",
385 			    sr.bits.ldw.sr));
386 			status = NPI_VIR_SR_INVALID(sr.bits.ldw.funcid);
387 			break;
388 		}
389 	} else {
390 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
391 		    " npi_dev_func_sr_lock_enter",
392 		    " tas busy", sr.bits.ldw));
393 		status = NPI_VIR_TAS_BUSY(sr.bits.ldw.funcid);
394 	}
395 
396 	return (status);
397 }
398 
399 /*
400  * npi_dev_func_sr_lock_free():
401  *	This function is called to free the function shared register
402  *	by setting the lock state to free.
403  * Parameters:
404  *	handle		- NPI handle
405  * Return:
406  *	NPI_SUCCESS	- If the function id can free the lock.
407  *
408  *	Error:
409  *	NPI_FAILURE
410  *		VIR_SR_NOTOWNER
411  *		VIR_TAS_NOTREAD
412  */
413 
414 npi_status_t
415 npi_dev_func_sr_lock_free(npi_handle_t handle)
416 {
417 	dev_func_sr_t		sr;
418 	int			status = NPI_SUCCESS;
419 
420 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
421 	if (sr.bits.ldw.tas) {
422 		if (sr.bits.ldw.funcid == NPI_GET_LOCK_OWNER(sr.bits.ldw.sr)) {
423 			sr.bits.ldw.sr &= NPI_DEV_SR_IMPL_ST_MASK;
424 			sr.bits.ldw.sr |= NPI_DEV_SR_LOCK_ST_FREE;
425 			sr.bits.ldw.tas = 0;
426 			NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
427 		} else {
428 			NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
429 			    " npi_dev_func_sr_lock_free"
430 			    " not owner <0x%x>",
431 			    sr.bits.ldw.sr));
432 			status = NPI_VIR_SR_NOTOWNER(sr.bits.ldw.funcid);
433 		}
434 	} else {
435 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
436 		    " npi_dev_func_sr_lock_free",
437 		    " invalid tas state <0x%x>",
438 		    sr.bits.ldw.tas));
439 		status = NPI_VIR_TAS_NOTREAD(sr.bits.ldw.funcid);
440 	}
441 
442 	return (status);
443 }
444 
445 /*
446  * npi_dev_func_sr_funcid_get():
447  *	This function is called to get the caller's function ID.
448  *	(based on address bits [25:26] on read access.
449  *	(After read, the TAS bit is always set to 1. Software needs
450  *	to write 0 to clear.) This function will write 0 to clear
451  *	the TAS bit if we own it.
452  * Parameters:
453  *	handle		- NPI handle
454  *	funcid_p	- pointer to store the function id.
455  * Return:
456  *	NPI_SUCCESS	- If get function id is complete successfully.
457  *
458  *	Error:
459  */
460 
461 npi_status_t
462 npi_dev_func_sr_funcid_get(npi_handle_t handle, uint8_t *funcid_p)
463 {
464 	dev_func_sr_t		sr;
465 
466 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
467 	*funcid_p = NXGE_VAL(DEV_FUNC_SR_FUNCID, sr.value);
468 	if (!sr.bits.ldw.tas) {
469 		/*
470 		 * After read, this bit is set to 1 by hardware.
471 		 * We own it if tas bit read as 0.
472 		 */
473 		sr.bits.ldw.tas = 0;
474 		NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
475 	}
476 
477 	return (NPI_SUCCESS);
478 }
479 
480 /*
481  * npi_dev_func_sr_sr_get():
482  *	This function is called to get the shared register value.
483  *	(After read, the TAS bit is always set to 1. Software needs
484  *	to write 0 to clear if we own it.)
485  *
486  * Parameters:
487  *	handle		- NPI handle
488  *	sr_p		- pointer to store the shared value of this register.
489  *
490  * Return:
491  *	NPI_SUCCESS		- If shared value get is complete successfully.
492  *
493  *	Error:
494  */
495 npi_status_t
496 npi_dev_func_sr_sr_raw_get(npi_handle_t handle, uint16_t *sr_p)
497 {
498 	dev_func_sr_t		sr;
499 
500 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
501 	*sr_p = NXGE_VAL(DEV_FUNC_SR_FUNCID, sr.value);
502 	if (!sr.bits.ldw.tas) {
503 		/*
504 		 * After read, this bit is set to 1 by hardware.
505 		 * We own it if tas bit read as 0.
506 		 */
507 		sr.bits.ldw.tas = 0;
508 		NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
509 	}
510 
511 	return (NPI_SUCCESS);
512 }
513 
514 /*
515  * npi_dev_func_sr_sr_get():
516  *	This function is called to get the shared register value.
517  *	(After read, the TAS bit is always set to 1. Software needs
518  *	to write 0 to clear if we own it.)
519  *
520  * Parameters:
521  *	handle	- NPI handle
522  *	sr_p	- pointer to store the shared value of this register.
523  *		. this will get only non-lock, non-function id portion
524  *              . of the register
525  *
526  *
527  * Return:
528  *	NPI_SUCCESS		- If shared value get is complete successfully.
529  *
530  *	Error:
531  */
532 
533 npi_status_t
534 npi_dev_func_sr_sr_get(npi_handle_t handle, uint16_t *sr_p)
535 {
536 	dev_func_sr_t		sr;
537 	uint16_t sr_impl = 0;
538 
539 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
540 	sr_impl = NXGE_VAL(DEV_FUNC_SR_FUNCID, sr.value);
541 	*sr_p =  (sr_impl << NPI_DEV_SR_IMPL_ST_SHIFT);
542 	if (!sr.bits.ldw.tas) {
543 		/*
544 		 * After read, this bit is set to 1 by hardware.
545 		 * We own it if tas bit read as 0.
546 		 */
547 		sr.bits.ldw.tas = 0;
548 		NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
549 	}
550 
551 	return (NPI_SUCCESS);
552 }
553 
554 /*
555  * npi_dev_func_sr_sr_get_set_clear():
556  *	This function is called to set the shared register value.
557  *	(Shared register must be read first. If tas bit is 0, then
558  *	it implies that the software can proceed to set). After
559  *	setting, tas bit will be cleared.
560  * Parameters:
561  *	handle		- NPI handle
562  *	impl_sr		- shared value to set (only the 8 bit
563  *			  implementation specific state info).
564  *
565  * Return:
566  *	NPI_SUCCESS		- If shared value is set successfully.
567  *
568  *	Error:
569  *	NPI_FAILURE
570  *		VIR_TAS_BUSY
571  */
572 
573 npi_status_t
574 npi_dev_func_sr_sr_get_set_clear(npi_handle_t handle, uint16_t impl_sr)
575 {
576 	dev_func_sr_t		sr;
577 	int			status;
578 
579 	status = npi_dev_func_sr_lock_enter(handle);
580 	if (status != NPI_SUCCESS) {
581 		NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
582 		    " npi_dev_func_sr_src_get_set_clear"
583 		    " unable to acquire lock:"
584 		    " status <0x%x>", status));
585 		return (status);
586 	}
587 
588 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
589 	sr.bits.ldw.sr |= (impl_sr << NPI_DEV_SR_IMPL_ST_SHIFT);
590 	NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
591 
592 	return (npi_dev_func_sr_lock_free(handle));
593 }
594 
595 /*
596  * npi_dev_func_sr_sr_set_only():
597  *	This function is called to only set the shared register value.
598  * Parameters:
599  *	handle		- NPI handle
600  *	impl_sr		- shared value to set.
601  *
602  * Return:
603  *	NPI_SUCCESS		- If shared value is set successfully.
604  *
605  *	Error:
606  *	NPI_FAILURE
607  *		VIR_TAS_BUSY
608  */
609 
610 npi_status_t
611 npi_dev_func_sr_sr_set_only(npi_handle_t handle, uint16_t impl_sr)
612 {
613 	int		status = NPI_SUCCESS;
614 	dev_func_sr_t	sr;
615 
616 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
617 	/* must be the owner */
618 	if (sr.bits.ldw.funcid == NPI_GET_LOCK_OWNER(sr.bits.ldw.sr)) {
619 		sr.bits.ldw.sr |= (impl_sr << NPI_DEV_SR_IMPL_ST_SHIFT);
620 		NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
621 	} else {
622 		NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
623 		    " npi_dev_func_sr_sr_set_only"
624 		    " not owner <0x%x>",
625 		    sr.bits.ldw.sr));
626 		status = NPI_VIR_SR_NOTOWNER(sr.bits.ldw.funcid);
627 	}
628 
629 	return (status);
630 }
631 
632 /*
633  * npi_dev_func_sr_busy():
634  *	This function is called to see if we can own the device.
635  *	It will not reset the tas bit.
636  * Parameters:
637  *	handle		- NPI handle
638  *	busy_p		- pointer to store busy flag.
639  *				(B_TRUE: device is in use, B_FALSE: free).
640  * Return:
641  *	NPI_SUCCESS		- If tas bit is read successfully.
642  *	Error:
643  */
644 
645 npi_status_t
646 npi_dev_func_sr_busy(npi_handle_t handle, boolean_t *busy_p)
647 {
648 	dev_func_sr_t	sr;
649 
650 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
651 	if (!sr.bits.ldw.tas) {
652 		sr.bits.ldw.tas = 0;
653 		NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
654 		*busy_p = B_FALSE;
655 	} else {
656 		/* Other function already owns it */
657 		*busy_p = B_TRUE;
658 	}
659 
660 	return (NPI_SUCCESS);
661 }
662 
663 /*
664  * npi_dev_func_sr_tas_get():
665  *	This function is called to get the tas bit
666  *	(after read, this bit is always set to 1, software write 0
667  *	 to clear it).
668  *
669  * Parameters:
670  *	handle		- NPI handle
671  *	tas_p		- pointer to store the tas value
672  *
673  * Return:
674  *	NPI_SUCCESS		- If tas value get is complete successfully.
675  *	Error:
676  */
677 
678 npi_status_t
679 npi_dev_func_sr_tas_get(npi_handle_t handle, uint8_t *tas_p)
680 {
681 	dev_func_sr_t		sr;
682 
683 	NXGE_REG_RD64(handle, DEV_FUNC_SR_REG, &sr.value);
684 	*tas_p = sr.bits.ldw.tas;
685 	if (!sr.bits.ldw.tas) {
686 		sr.bits.ldw.tas = 0;
687 		NXGE_REG_WR64(handle, DEV_FUNC_SR_REG, sr.value);
688 
689 	}
690 
691 	return (NPI_SUCCESS);
692 }
693 
694 /*
695  * npi_fzc_mpc_set():
696  *	This function is called to enable the write access
697  *	to FZC region to function zero.
698  * Parameters:
699  *	handle		- NPI handle
700  * Return:
701  *	NPI_SUCCESS	-
702  *	Error:
703  */
704 
705 npi_status_t
706 npi_fzc_mpc_set(npi_handle_t handle, boolean_t mpc)
707 {
708 	multi_part_ctl_t	mp;
709 
710 	mp.value = 0;
711 	if (mpc) {
712 		mp.bits.ldw.mpc = 1;
713 	}
714 	NXGE_REG_WR64(handle, MULTI_PART_CTL_REG, mp.value);
715 
716 	return (NPI_SUCCESS);
717 }
718 
719 /*
720  * npi_fzc_mpc_get():
721  *	This function is called to get the access mode.
722  * Parameters:
723  *	handle		- NPI handle
724  * Return:
725  *	NPI_SUCCESS	-
726  *
727  */
728 
729 npi_status_t
730 npi_fzc_mpc_get(npi_handle_t handle, boolean_t *mpc_p)
731 {
732 	multi_part_ctl_t	mpc;
733 
734 	mpc.value = 0;
735 	NXGE_REG_RD64(handle, MULTI_PART_CTL_REG, &mpc.value);
736 	*mpc_p = mpc.bits.ldw.mpc;
737 
738 	return (NPI_SUCCESS);
739 }
740 
741 /*
742  * npi_fzc_dma_bind_set():
743  *	This function is called to set DMA binding register.
744  * Parameters:
745  *	handle		- NPI handle
746  *	dma_bind	- NPI defined data structure that
747  *			  contains the tx/rx channel binding info.
748  *			  to set.
749  * Return:
750  *	NPI_SUCCESS	-
751  *	Error:
752  *	NPI_FAILURE
753  *
754  */
755 
756 npi_status_t
757 npi_fzc_dma_bind_set(npi_handle_t handle, fzc_dma_bind_t dma_bind)
758 {
759 	dma_bind_t	bind;
760 	int		status;
761 	uint8_t		fn, region, id, tn, rn;
762 
763 	fn = dma_bind.function_id;
764 	region = dma_bind.sub_vir_region;
765 	id = dma_bind.vir_index;
766 	tn = dma_bind.tx_channel;
767 	rn = dma_bind.rx_channel;
768 
769 	DMA_BIND_VADDR_VALIDATE(fn, region, id, status);
770 	if (status) {
771 		return (status);
772 	}
773 
774 	if (dma_bind.tx_bind) {
775 		DMA_BIND_TX_VALIDATE(tn, status);
776 		if (status) {
777 			return (status);
778 		}
779 	}
780 
781 	if (dma_bind.rx_bind) {
782 		DMA_BIND_RX_VALIDATE(rn, status);
783 		if (status) {
784 			return (status);
785 		}
786 	}
787 
788 	bind.value = 0;
789 	if (dma_bind.tx_bind) {
790 		bind.bits.ldw.tx_bind = 1;
791 		bind.bits.ldw.tx = tn;
792 	}
793 	if (dma_bind.rx_bind) {
794 		bind.bits.ldw.rx_bind = 1;
795 		bind.bits.ldw.rx = rn;
796 	}
797 
798 	NXGE_REG_WR64(handle, DMA_BIND_REG +
799 	    DMA_BIND_REG_OFFSET(fn, region, id), bind.value);
800 
801 	return (status);
802 }
803 
804 npi_status_t
805 npi_fzc_dma_bind_get(
806 	npi_handle_t handle,
807 	fzc_dma_bind_t dma_bind,
808 	uint64_t *pValue)
809 {
810 	uint8_t		function, region, slot;
811 	int		offset;
812 	int		status;
813 
814 	function = dma_bind.function_id;
815 	region = dma_bind.sub_vir_region;
816 	slot = dma_bind.vir_index;
817 
818 	DMA_BIND_VADDR_VALIDATE(function, region, slot, status);
819 	if (status) {
820 		return (status);
821 	}
822 
823 	offset = DMA_BIND_REG_OFFSET(function, region, slot);
824 	NXGE_REG_RD64(handle, DMA_BIND_REG + offset, pValue);
825 
826 	return (status);
827 }
828 
829 /*
830  * npi_fzc_ldg_num_set():
831  *	This function is called to set up a logical group number that
832  *	a logical device belongs to.
833  * Parameters:
834  *	handle		- NPI handle
835  *	ld		- logical device number (0 - 68)
836  *	ldg		- logical device group number (0 - 63)
837  * Return:
838  *	NPI_SUCCESS	-
839  *	Error:
840  *	NPI_FAILURE
841  *
842  */
843 
844 npi_status_t
845 npi_fzc_ldg_num_set(npi_handle_t handle, uint8_t ld, uint8_t ldg)
846 {
847 	ldg_num_t	gnum;
848 
849 	ASSERT(LD_VALID(ld));
850 	if (!LD_VALID(ld)) {
851 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
852 		    " npi_fzc_ldg_num_set"
853 		    "ld <0x%x>", ld));
854 		return (NPI_FAILURE | NPI_VIR_LD_INVALID(ld));
855 	}
856 
857 	ASSERT(LDG_VALID(ldg));
858 	if (!LDG_VALID(ldg)) {
859 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
860 		    " npi_fzc_ldg_num_set"
861 		    " ldg <0x%x>", ldg));
862 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(ld));
863 	}
864 
865 	gnum.value = 0;
866 	gnum.bits.ldw.num = ldg;
867 
868 	NXGE_REG_WR64(handle, LDG_NUM_REG + LD_NUM_OFFSET(ld),
869 	    gnum.value);
870 
871 	return (NPI_SUCCESS);
872 }
873 
874 /*
875  * npi_fzc_ldg_num_get():
876  *	This function is called to get the logical device group that
877  *	a logical device belongs to.
878  * Parameters:
879  *	handle		- NPI handle
880  *	ld		- logical device number (0 - 68)
881  *	*ldg_p		- pointer to store its group number.
882  * Return:
883  *	NPI_SUCCESS	-
884  *	Error:
885  *	NPI_FAILURE
886  */
887 
888 npi_status_t
889 npi_fzc_ldg_num_get(npi_handle_t handle, uint8_t ld, uint8_t *ldg_p)
890 {
891 	uint64_t val;
892 
893 	ASSERT(LD_VALID(ld));
894 	if (!LD_VALID(ld)) {
895 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
896 		    " npi_fzc_ldg_num_get"
897 		    " Invalid Input:",
898 		    " ld <0x%x>", ld));
899 		return (NPI_FAILURE | NPI_VIR_LD_INVALID(ld));
900 	}
901 
902 	NXGE_REG_RD64(handle, LDG_NUM_REG + LD_NUM_OFFSET(ld), &val);
903 
904 	*ldg_p = (uint8_t)(val & LDG_NUM_NUM_MASK);
905 
906 	return (NPI_SUCCESS);
907 }
908 
909 /*
910  * npi_ldsv_ldfs_get():
911  *	This function is called to get device state vectors.
912  * Parameters:
913  *	handle		- NPI handle
914  *	ldg		- logical device group (0 - 63)
915  *	*ldf_p		- pointer to store ldf0 and ldf1 flag bits.
916  * Return:
917  *	NPI_SUCCESS	-
918  *	Error:
919  *	NPI_FAILURE
920  */
921 
922 npi_status_t
923 npi_ldsv_ldfs_get(npi_handle_t handle, uint8_t ldg, uint64_t *vector0_p,
924 	uint64_t *vector1_p, uint64_t *vector2_p)
925 {
926 	int	status;
927 
928 	if ((status = npi_ldsv_get(handle, ldg, VECTOR0, vector0_p))) {
929 		return (status);
930 	}
931 	if ((status = npi_ldsv_get(handle, ldg, VECTOR1, vector1_p))) {
932 		return (status);
933 	}
934 	if ((status = npi_ldsv_get(handle, ldg, VECTOR2, vector2_p))) {
935 		return (status);
936 	}
937 
938 	return (NPI_SUCCESS);
939 }
940 
941 /*
942  * npi_ldsv_get():
943  *	This function is called to get device state vectors.
944  * Parameters:
945  *	handle		- NPI handle
946  *	ldg		- logical device group (0 - 63)
947  *	ldf_type	- either LDF0 (0) or LDF1 (1)
948  *	vector		- vector type (0, 1 or 2)
949  *	*ldf_p		- pointer to store its flag bits.
950  * Return:
951  *	NPI_SUCCESS	-
952  *	Error:
953  *	NPI_FAILURE
954  */
955 
956 npi_status_t
957 npi_ldsv_get(npi_handle_t handle, uint8_t ldg, ldsv_type_t vector,
958 	uint64_t *ldf_p)
959 {
960 	uint64_t		offset;
961 
962 	ASSERT(LDG_VALID(ldg));
963 	if (!LDG_VALID(ldg)) {
964 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
965 		    " npi_ldsv_get"
966 		    " Invalid Input "
967 		    " ldg <0x%x>", ldg));
968 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(ldg));
969 	}
970 
971 	switch (vector) {
972 	case VECTOR0:
973 		offset = LDSV0_REG + LDSV_OFFSET(ldg);
974 		break;
975 
976 	case VECTOR1:
977 		offset = LDSV1_REG + LDSV_OFFSET(ldg);
978 		break;
979 
980 	case VECTOR2:
981 		offset = LDSV2_REG + LDSV_OFFSET(ldg);
982 		break;
983 
984 	default:
985 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
986 		    " npi_ldsv_get"
987 		    " Invalid Input: "
988 		    " ldsv type <0x%x>", vector));
989 		return (NPI_FAILURE | NPI_VIR_LDSV_INVALID(vector));
990 	}
991 
992 	NXGE_REG_RD64(handle, offset, ldf_p);
993 
994 	return (NPI_SUCCESS);
995 }
996 
997 /*
998  * npi_ldsv_ld_get():
999  *	This function is called to get the flag bit value of a device.
1000  * Parameters:
1001  *	handle		- NPI handle
1002  *	ldg		- logical device group (0 - 63)
1003  *	ld		- logical device (0 - 68)
1004  *	ldf_type	- either LDF0 (0) or LDF1 (1)
1005  *	vector		- vector type (0, 1 or 2)
1006  *	*ldf_p		- pointer to store its flag bits.
1007  * Return:
1008  *	NPI_SUCCESS	-
1009  *	Error:
1010  *	NPI_FAILURE
1011  */
1012 
1013 npi_status_t
1014 npi_ldsv_ld_get(npi_handle_t handle, uint8_t ldg, uint8_t ld,
1015 	ldsv_type_t vector, ldf_type_t ldf_type, boolean_t *flag_p)
1016 {
1017 	uint64_t		sv;
1018 	uint64_t		offset;
1019 
1020 	ASSERT(LDG_VALID(ldg));
1021 	if (!LDG_VALID(ldg)) {
1022 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1023 		    " npi_ldsv_ld_get"
1024 		    " Invalid Input: "
1025 		    " ldg <0x%x>", ldg));
1026 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(ldg));
1027 	}
1028 	ASSERT((LD_VALID(ld)) &&	\
1029 	    ((vector != VECTOR2) || (ld >= NXGE_MAC_LD_START)));
1030 	if (!LD_VALID(ld)) {
1031 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1032 		    " npi_ldsv_ld_get Invalid Input: "
1033 		    " ld <9x%x>", ld));
1034 		return (NPI_FAILURE | NPI_VIR_LD_INVALID(ld));
1035 	} else if (vector == VECTOR2 && ld < NXGE_MAC_LD_START) {
1036 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1037 		    " npi_ldsv_ld_get Invalid Input:"
1038 		    " ld-vector2 <0x%x>", ld));
1039 		return (NPI_FAILURE | NPI_VIR_LD_INVALID(ld));
1040 	}
1041 
1042 	switch (vector) {
1043 	case VECTOR0:
1044 		offset = LDSV0_REG + LDSV_OFFSET(ldg);
1045 		break;
1046 
1047 	case VECTOR1:
1048 		offset = LDSV1_REG + LDSV_OFFSET(ldg);
1049 		break;
1050 
1051 	case VECTOR2:
1052 		offset = LDSV2_REG + LDSV_OFFSET(ldg);
1053 		break;
1054 
1055 	default:
1056 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, "npi_ldsv_get"
1057 		    "ldsv", vector));
1058 		return (NPI_FAILURE | NPI_VIR_LDSV_INVALID(vector));
1059 	}
1060 
1061 	NXGE_REG_RD64(handle, offset, &sv);
1062 	if (vector != VECTOR2) {
1063 		*flag_p = ((sv >> ld) & LDSV_MASK_ALL);
1064 	} else {
1065 		if (ldf_type) {
1066 			*flag_p = (((sv >> LDSV2_LDF1_SHIFT) >>
1067 			    (ld - NXGE_MAC_LD_START)) & LDSV_MASK_ALL);
1068 		} else {
1069 			*flag_p = (((sv >> LDSV2_LDF0_SHIFT) >>
1070 			    (ld - NXGE_MAC_LD_START)) & LDSV_MASK_ALL);
1071 		}
1072 	}
1073 
1074 	return (NPI_SUCCESS);
1075 }
1076 
1077 /*
1078  * npi_ldsv_ld_ldf0_get():
1079  *	This function is called to get the ldf0 bit value of a device.
1080  * Parameters:
1081  *	handle		- NPI handle
1082  *	ldg		- logical device group (0 - 63)
1083  *	ld		- logical device (0 - 68)
1084  *	*ldf_p		- pointer to store its flag bits.
1085  * Return:
1086  *	NPI_SUCCESS	-
1087  *	Error:
1088  *	NPI_FAILURE
1089  */
1090 
1091 npi_status_t
1092 npi_ldsv_ld_ldf0_get(npi_handle_t handle, uint8_t ldg, uint8_t ld,
1093 	boolean_t *flag_p)
1094 {
1095 	ldsv_type_t vector;
1096 
1097 	if (ld >= NXGE_MAC_LD_START) {
1098 		vector = VECTOR2;
1099 	}
1100 
1101 	return (npi_ldsv_ld_get(handle, ldg, ld, vector, LDF0, flag_p));
1102 }
1103 
1104 /*
1105  * npi_ldsv_ld_ldf1_get():
1106  *	This function is called to get the ldf1 bit value of a device.
1107  * Parameters:
1108  *	handle		- NPI handle
1109  *	ldg		- logical device group (0 - 63)
1110  *	ld		- logical device (0 - 68)
1111  *	*ldf_p		- pointer to store its flag bits.
1112  * Return:
1113  *	NPI_SUCCESS	-
1114  *	Error:
1115  *	NPI_FAILURE
1116  */
1117 
1118 npi_status_t
1119 npi_ldsv_ld_ldf1_get(npi_handle_t handle, uint8_t ldg, uint8_t ld,
1120 		boolean_t *flag_p)
1121 {
1122 	ldsv_type_t vector;
1123 
1124 	if (ld >= NXGE_MAC_LD_START) {
1125 		vector = VECTOR2;
1126 	}
1127 
1128 	return (npi_ldsv_ld_get(handle, ldg, ld, vector, LDF1, flag_p));
1129 }
1130 
1131 /*
1132  * npi_intr_mask_set():
1133  *	This function is called to select the mask bits for both ldf0 and ldf1.
1134  * Parameters:
1135  *	handle		- NPI handle
1136  *	ld		- logical device (0 - 68)
1137  *	ldf_mask	- mask value to set (both ldf0 and ldf1).
1138  * Return:
1139  *	NPI_SUCCESS	-
1140  *	Error:
1141  *	NPI_FAILURE
1142  */
1143 
1144 npi_status_t
1145 npi_intr_mask_set(npi_handle_t handle, uint8_t ld, uint8_t ldf_mask)
1146 {
1147 	uint64_t		offset;
1148 
1149 	ASSERT(LD_VALID(ld));
1150 	if (!LD_VALID(ld)) {
1151 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1152 		    " npi_intr_mask_set ld", ld));
1153 		return (NPI_FAILURE | NPI_VIR_LD_INVALID(ld));
1154 	}
1155 
1156 	ldf_mask &= LD_IM0_MASK;
1157 	offset = LDSV_OFFSET_MASK(ld);
1158 
1159 	NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
1160 	    "npi_intr_mask_set: ld %d "
1161 	    " offset 0x%0llx "
1162 	    " mask 0x%x",
1163 	    ld, offset, ldf_mask));
1164 
1165 	NXGE_REG_WR64(handle, offset, (uint64_t)ldf_mask);
1166 
1167 	return (NPI_SUCCESS);
1168 }
1169 
1170 /*
1171  * npi_intr_mask_get():
1172  *	This function is called to get the mask bits.
1173  * Parameters:
1174  *	handle		- NPI handle
1175  *	ld		- logical device (0 - 68)
1176  *	ldf_mask	- pointer to store mask bits info.
1177  * Return:
1178  *	NPI_SUCCESS	-
1179  *	Error:
1180  *	NPI_FAILURE
1181  */
1182 npi_status_t
1183 npi_intr_mask_get(npi_handle_t handle, uint8_t ld, uint8_t *ldf_mask_p)
1184 {
1185 	uint64_t		offset;
1186 	uint64_t		val;
1187 
1188 	ASSERT(LD_VALID(ld));
1189 	if (!LD_VALID(ld)) {
1190 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1191 		    " npi_intr_mask_get ld", ld));
1192 		return (NPI_FAILURE | NPI_VIR_LD_INVALID(ld));
1193 	}
1194 
1195 	offset = LDSV_OFFSET_MASK(ld);
1196 
1197 	NXGE_REG_RD64(handle, offset, &val);
1198 
1199 	*ldf_mask_p = (uint8_t)(val & LD_IM_MASK);
1200 
1201 	return (NPI_SUCCESS);
1202 }
1203 
1204 /*
1205  * npi_intr_ldg_mgmt_set():
1206  *	This function is called to set interrupt timer and arm bit.
1207  * Parameters:
1208  *	handle		- NPI handle
1209  *	ldg		- logical device group (0 - 63)
1210  *	arm		- B_TRUE (arm) B_FALSE (disable)
1211  * Return:
1212  *	NPI_SUCCESS	-
1213  *	Error:
1214  *	NPI_FAILURE
1215  */
1216 
1217 npi_status_t
1218 npi_intr_ldg_mgmt_set(npi_handle_t handle, uint8_t ldg, boolean_t arm,
1219 			uint8_t timer)
1220 {
1221 	ldgimgm_t		mgm;
1222 	uint64_t		val;
1223 
1224 	ASSERT((LDG_VALID(ldg)) && (LD_INTTIMER_VALID(timer)));
1225 	if (!LDG_VALID(ldg)) {
1226 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1227 		    " npi_intr_ldg_mgmt_set"
1228 		    " Invalid Input: "
1229 		    " ldg <0x%x>", ldg));
1230 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(ldg));
1231 	}
1232 	if (!LD_INTTIMER_VALID(timer)) {
1233 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1234 		    " npi_intr_ldg_mgmt_set Invalid Input"
1235 		    " timer <0x%x>", timer));
1236 		return (NPI_FAILURE | NPI_VIR_INTM_TM_INVALID(ldg));
1237 	}
1238 
1239 	if (arm) {
1240 		mgm.bits.ldw.arm = 1;
1241 	} else {
1242 		NXGE_REG_RD64(handle, LDGIMGN_REG + LDSV_OFFSET(ldg), &val);
1243 		mgm.value = val & LDGIMGM_ARM_MASK;
1244 	}
1245 
1246 	mgm.bits.ldw.timer = timer;
1247 	NXGE_REG_WR64(handle, LDGIMGN_REG + LDSV_OFFSET(ldg),
1248 	    mgm.value);
1249 
1250 	NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
1251 	    " npi_intr_ldg_mgmt_set: ldg %d"
1252 	    " reg offset 0x%x",
1253 	    ldg, LDGIMGN_REG + LDSV_OFFSET(ldg)));
1254 
1255 	return (NPI_SUCCESS);
1256 }
1257 
1258 /*
1259  * npi_intr_ldg_mgmt_timer_get():
1260  *	This function is called to get the timer counter
1261  * Parameters:
1262  *	handle		- NPI handle
1263  *	ldg		- logical device group (0 - 63)
1264  *	timer_p		- pointer to store the timer counter.
1265  * Return:
1266  *	NPI_SUCCESS	-
1267  *	Error:
1268  *	NPI_FAILURE
1269  */
1270 
1271 npi_status_t
1272 npi_intr_ldg_mgmt_timer_get(npi_handle_t handle, uint8_t ldg, uint8_t *timer_p)
1273 {
1274 	uint64_t val;
1275 
1276 	ASSERT(LDG_VALID(ldg));
1277 	if (!LDG_VALID(ldg)) {
1278 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1279 		    " npi_intr_ldg_mgmt_timer_get"
1280 		    " Invalid Input: ldg <0x%x>", ldg));
1281 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(ldg));
1282 	}
1283 
1284 	NXGE_REG_RD64(handle, LDGIMGN_REG + LDSV_OFFSET(ldg), &val);
1285 
1286 	*timer_p = (uint8_t)(val & LDGIMGM_TIMER_MASK);
1287 
1288 	NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
1289 	    " npi_intr_ldg_mgmt_timer_get: ldg %d"
1290 	    " reg offset 0x%x",
1291 	    ldg, LDGIMGN_REG + LDSV_OFFSET(ldg)));
1292 
1293 	return (NPI_SUCCESS);
1294 }
1295 
1296 /*
1297  * npi_intr_ldg_mgmt_arm():
1298  *	This function is called to arm the group.
1299  * Parameters:
1300  *	handle		- NPI handle
1301  *	ldg		- logical device group (0 - 63)
1302  * Return:
1303  *	NPI_SUCCESS	-
1304  *	Error:
1305  *	NPI_FAILURE
1306  */
1307 
1308 npi_status_t
1309 npi_intr_ldg_mgmt_arm(npi_handle_t handle, uint8_t ldg)
1310 {
1311 	ldgimgm_t		mgm;
1312 
1313 	ASSERT(LDG_VALID(ldg));
1314 	if (!LDG_VALID(ldg)) {
1315 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1316 		    " npi_intr_ldg_mgmt_arm"
1317 		    " Invalid Input: ldg <0x%x>",
1318 		    ldg));
1319 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(ldg));
1320 	}
1321 
1322 	NXGE_REG_RD64(handle, (LDGIMGN_REG + LDSV_OFFSET(ldg)), &mgm.value);
1323 	mgm.bits.ldw.arm = 1;
1324 
1325 	NXGE_REG_WR64(handle, LDGIMGN_REG + LDSV_OFFSET(ldg),
1326 	    mgm.value);
1327 	NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
1328 	    " npi_intr_ldg_mgmt_arm: ldg %d"
1329 	    " reg offset 0x%x",
1330 	    ldg, LDGIMGN_REG + LDSV_OFFSET(ldg)));
1331 
1332 	return (NPI_SUCCESS);
1333 }
1334 
1335 /*
1336  * npi_fzc_ldg_timer_res_set():
1337  *	This function is called to set the timer resolution.
1338  * Parameters:
1339  *	handle		- NPI handle
1340  *	res		- timer resolution (# of system clocks)
1341  * Return:
1342  *	NPI_SUCCESS	-
1343  *	Error:
1344  *	NPI_FAILURE
1345  */
1346 
1347 npi_status_t
1348 npi_fzc_ldg_timer_res_set(npi_handle_t handle, uint32_t res)
1349 {
1350 	ASSERT(res <= LDGTITMRES_RES_MASK);
1351 	if (res > LDGTITMRES_RES_MASK) {
1352 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1353 		    " npi_fzc_ldg_timer_res_set"
1354 		    " Invalid Input: res <0x%x>",
1355 		    res));
1356 		return (NPI_FAILURE | NPI_VIR_TM_RES_INVALID);
1357 	}
1358 
1359 	NXGE_REG_WR64(handle, LDGITMRES_REG, (res & LDGTITMRES_RES_MASK));
1360 
1361 	return (NPI_SUCCESS);
1362 }
1363 
1364 /*
1365  * npi_fzc_ldg_timer_res_get():
1366  *	This function is called to get the timer resolution.
1367  * Parameters:
1368  *	handle		- NPI handle
1369  *	res_p		- pointer to store the timer resolution.
1370  * Return:
1371  *	NPI_SUCCESS	-
1372  *	Error:
1373  *	NPI_FAILURE
1374  */
1375 
1376 npi_status_t
1377 npi_fzc_ldg_timer_res_get(npi_handle_t handle, uint8_t *res_p)
1378 {
1379 	uint64_t val;
1380 
1381 	NXGE_REG_RD64(handle, LDGITMRES_REG, &val);
1382 
1383 	*res_p = (uint8_t)(val & LDGIMGM_TIMER_MASK);
1384 
1385 	return (NPI_SUCCESS);
1386 }
1387 
1388 /*
1389  * npi_fzc_sid_set():
1390  *	This function is called to set the system interrupt data.
1391  * Parameters:
1392  *	handle		- NPI handle
1393  *	ldg		- logical group (0 - 63)
1394  *	sid		- NPI defined data to set
1395  * Return:
1396  *	NPI_SUCCESS	-
1397  *	Error:
1398  *	NPI_FAILURE
1399  */
1400 
1401 npi_status_t
1402 npi_fzc_sid_set(npi_handle_t handle, fzc_sid_t sid)
1403 {
1404 	sid_t		sd;
1405 
1406 	ASSERT(LDG_VALID(sid.ldg));
1407 	if (!LDG_VALID(sid.ldg)) {
1408 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1409 		    " npi_fzc_sid_set"
1410 		    " Invalid Input: ldg <0x%x>",
1411 		    sid.ldg));
1412 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(sid.ldg));
1413 	}
1414 	if (!sid.niu) {
1415 		ASSERT(FUNC_VALID(sid.func));
1416 		if (!FUNC_VALID(sid.func)) {
1417 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1418 			    " npi_fzc_sid_set"
1419 			    " Invalid Input: func <0x%x>",
1420 			    sid.func));
1421 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1422 			    "invalid FUNC: npi_fzc_sid_set(%d)", sid.func));
1423 			return (NPI_FAILURE | NPI_VIR_FUNC_INVALID(sid.func));
1424 		}
1425 
1426 		ASSERT(SID_VECTOR_VALID(sid.vector));
1427 		if (!SID_VECTOR_VALID(sid.vector)) {
1428 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1429 			    " npi_fzc_sid_set"
1430 			    " Invalid Input: vector <0x%x>",
1431 			    sid.vector));
1432 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1433 			    " invalid VECTOR: npi_fzc_sid_set(%d)",
1434 			    sid.vector));
1435 			return (NPI_FAILURE |
1436 			    NPI_VIR_SID_VEC_INVALID(sid.vector));
1437 		}
1438 	}
1439 	sd.value = 0;
1440 	if (!sid.niu) {
1441 		sd.bits.ldw.data = ((sid.func << SID_DATA_FUNCNUM_SHIFT) |
1442 		    (sid.vector & SID_DATA_INTNUM_MASK));
1443 	}
1444 
1445 	NPI_DEBUG_MSG((handle.function, NPI_VIR_CTL,
1446 	    " npi_fzc_sid_set: group %d 0x%llx", sid.ldg, sd.value));
1447 
1448 	NXGE_REG_WR64(handle,  SID_REG + LDG_SID_OFFSET(sid.ldg), sd.value);
1449 
1450 	return (NPI_SUCCESS);
1451 }
1452 
1453 /*
1454  * npi_fzc_sid_get():
1455  *	This function is called to get the system interrupt data.
1456  * Parameters:
1457  *	handle		- NPI handle
1458  *	ldg		- logical group (0 - 63)
1459  *	sid_p		- NPI defined data to get
1460  * Return:
1461  *	NPI_SUCCESS	-
1462  *	Error:
1463  *	NPI_FAILURE
1464  */
1465 
1466 npi_status_t
1467 npi_fzc_sid_get(npi_handle_t handle, p_fzc_sid_t sid_p)
1468 {
1469 	sid_t		sd;
1470 
1471 	ASSERT(LDG_VALID(sid_p->ldg));
1472 	if (!LDG_VALID(sid_p->ldg)) {
1473 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1474 		    " npi_fzc_sid_get"
1475 		    " Invalid Input: ldg <0x%x>",
1476 		    sid_p->ldg));
1477 		return (NPI_FAILURE | NPI_VIR_LDG_INVALID(sid_p->ldg));
1478 	}
1479 	NXGE_REG_RD64(handle, (SID_REG + LDG_SID_OFFSET(sid_p->ldg)),
1480 	    &sd.value);
1481 	if (!sid_p->niu) {
1482 		sid_p->func = ((sd.bits.ldw.data & SID_DATA_FUNCNUM_MASK) >>
1483 		    SID_DATA_FUNCNUM_SHIFT);
1484 		sid_p->vector = ((sd.bits.ldw.data & SID_DATA_INTNUM_MASK) >>
1485 		    SID_DATA_INTNUM_SHIFT);
1486 	} else {
1487 		sid_p->vector = (sd.value & SID_DATA_MASK);
1488 	}
1489 
1490 	return (NPI_SUCCESS);
1491 }
1492 
1493 /*
1494  * npi_fzc_sys_err_mask_set():
1495  *	This function is called to mask/unmask the device error mask bits.
1496  *
1497  * Parameters:
1498  *	handle		- NPI handle
1499  *	mask		- set bit mapped mask
1500  * Return:
1501  *	NPI_SUCCESS	-
1502  *	Error:
1503  *	NPI_FAILURE
1504  */
1505 
1506 npi_status_t
1507 npi_fzc_sys_err_mask_set(npi_handle_t handle, uint64_t mask)
1508 {
1509 	NXGE_REG_WR64(handle,  SYS_ERR_MASK_REG, mask);
1510 	return (NPI_SUCCESS);
1511 }
1512 
1513 /*
1514  * npi_fzc_sys_err_stat_get():
1515  *	This function is called to get the system error stats.
1516  *
1517  * Parameters:
1518  *	handle		- NPI handle
1519  *	err_stat	- sys_err_stat structure to hold stats.
1520  * Return:
1521  *	NPI_SUCCESS	-
1522  *	Error:
1523  *	NPI_FAILURE
1524  */
1525 
1526 npi_status_t
1527 npi_fzc_sys_err_stat_get(npi_handle_t handle, p_sys_err_stat_t statp)
1528 {
1529 	NXGE_REG_RD64(handle,  SYS_ERR_STAT_REG, &statp->value);
1530 	return (NPI_SUCCESS);
1531 }
1532 
1533 npi_status_t
1534 npi_fzc_rst_ctl_get(npi_handle_t handle, p_rst_ctl_t rstp)
1535 {
1536 	NXGE_REG_RD64(handle, RST_CTL_REG, &rstp->value);
1537 
1538 	return (NPI_SUCCESS);
1539 }
1540 
1541 /*
1542  * npi_fzc_mpc_get():
1543  *	This function is called to get the access mode.
1544  * Parameters:
1545  *	handle		- NPI handle
1546  * Return:
1547  *	NPI_SUCCESS	-
1548  *
1549  */
1550 
1551 npi_status_t
1552 npi_fzc_rst_ctl_reset_mac(npi_handle_t handle, uint8_t port)
1553 {
1554 	rst_ctl_t 		rst;
1555 
1556 	rst.value = 0;
1557 	NXGE_REG_RD64(handle, RST_CTL_REG, &rst.value);
1558 	rst.value |= (1 << (RST_CTL_MAC_RST0_SHIFT + port));
1559 	NXGE_REG_WR64(handle, RST_CTL_REG, rst.value);
1560 
1561 	return (NPI_SUCCESS);
1562 }
1563