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