xref: /illumos-gate/usr/src/uts/common/io/nxge/npi/npi_txc.c (revision d48be21240dfd051b689384ce2b23479d757f2d8)
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_txc.h>
27 
28 /*
29  * Transmit Controller (TXC) Functions.
30  */
31 
32 uint64_t txc_fzc_dmc_offset[] = {
33 	TXC_DMA_MAX_BURST_REG,
34 	TXC_DMA_MAX_LENGTH_REG
35 };
36 
37 const char *txc_fzc_dmc_name[] = {
38 	"TXC_DMA_MAX_BURST_REG",
39 	"TXC_DMA_MAX_LENGTH_REG"
40 };
41 
42 uint64_t txc_fzc_offset [] = {
43 	TXC_CONTROL_REG,
44 	TXC_TRAINING_REG,
45 	TXC_DEBUG_SELECT_REG,
46 	TXC_MAX_REORDER_REG,
47 	TXC_INT_STAT_DBG_REG,
48 	TXC_INT_STAT_REG,
49 	TXC_INT_MASK_REG
50 };
51 
52 const char *txc_fzc_name [] = {
53 	"TXC_CONTROL_REG",
54 	"TXC_TRAINING_REG",
55 	"TXC_DEBUG_SELECT_REG",
56 	"TXC_MAX_REORDER_REG",
57 	"TXC_INT_STAT_DBG_REG",
58 	"TXC_INT_STAT_REG",
59 	"TXC_INT_MASK_REG"
60 };
61 
62 uint64_t txc_fzc_port_offset[] = {
63 	TXC_PORT_CTL_REG,
64 	TXC_PORT_DMA_ENABLE_REG,
65 	TXC_PKT_STUFFED_REG,
66 	TXC_PKT_XMIT_REG,
67 	TXC_ROECC_CTL_REG,
68 	TXC_ROECC_ST_REG,
69 	TXC_RO_DATA0_REG,
70 	TXC_RO_DATA1_REG,
71 	TXC_RO_DATA2_REG,
72 	TXC_RO_DATA3_REG,
73 	TXC_RO_DATA4_REG,
74 	TXC_SFECC_CTL_REG,
75 	TXC_SFECC_ST_REG,
76 	TXC_SF_DATA0_REG,
77 	TXC_SF_DATA1_REG,
78 	TXC_SF_DATA2_REG,
79 	TXC_SF_DATA3_REG,
80 	TXC_SF_DATA4_REG,
81 	TXC_RO_TIDS_REG,
82 	TXC_RO_STATE0_REG,
83 	TXC_RO_STATE1_REG,
84 	TXC_RO_STATE2_REG,
85 	TXC_RO_STATE3_REG,
86 	TXC_RO_CTL_REG,
87 	TXC_RO_ST_DATA0_REG,
88 	TXC_RO_ST_DATA1_REG,
89 	TXC_RO_ST_DATA2_REG,
90 	TXC_RO_ST_DATA3_REG,
91 	TXC_PORT_PACKET_REQ_REG
92 };
93 
94 const char *txc_fzc_port_name[] = {
95 	"TXC_PORT_CTL_REG",
96 	"TXC_PORT_DMA_ENABLE_REG",
97 	"TXC_PKT_STUFFED_REG",
98 	"TXC_PKT_XMIT_REG",
99 	"TXC_ROECC_CTL_REG",
100 	"TXC_ROECC_ST_REG",
101 	"TXC_RO_DATA0_REG",
102 	"TXC_RO_DATA1_REG",
103 	"TXC_RO_DATA2_REG",
104 	"TXC_RO_DATA3_REG",
105 	"TXC_RO_DATA4_REG",
106 	"TXC_SFECC_CTL_REG",
107 	"TXC_SFECC_ST_REG",
108 	"TXC_SF_DATA0_REG",
109 	"TXC_SF_DATA1_REG",
110 	"TXC_SF_DATA2_REG",
111 	"TXC_SF_DATA3_REG",
112 	"TXC_SF_DATA4_REG",
113 	"TXC_RO_TIDS_REG",
114 	"TXC_RO_STATE0_REG",
115 	"TXC_RO_STATE1_REG",
116 	"TXC_RO_STATE2_REG",
117 	"TXC_RO_STATE3_REG",
118 	"TXC_RO_CTL_REG",
119 	"TXC_RO_ST_DATA0_REG",
120 	"TXC_RO_ST_DATA1_REG",
121 	"TXC_RO_ST_DATA2_REG",
122 	"TXC_RO_ST_DATA3_REG",
123 	"TXC_PORT_PACKET_REQ_REG"
124 };
125 
126 /*
127  * npi_txc_dump_tdc_fzc_regs
128  * Dumps the contents of TXC csrs and fzc registers
129  *
130  * Input:
131  *	handle		- NPI handle
132  *         tdc:      TX DMA number
133  *
134  * return:
135  *     NPI_SUCCESS
136  *     NPI_FAILURE
137  *     NPI_TXC_CHANNEL_INVALID
138  *
139  */
140 npi_status_t
141 npi_txc_dump_tdc_fzc_regs(npi_handle_t handle, uint8_t tdc)
142 {
143 	uint64_t		value, offset;
144 	int 			num_regs, i;
145 
146 	ASSERT(TXDMA_CHANNEL_VALID(tdc));
147 	if (!TXDMA_CHANNEL_VALID(tdc)) {
148 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
149 		    "npi_txc_dump_tdc_fzc_regs"
150 		    " Invalid TDC number %d \n",
151 		    tdc));
152 		return (NPI_FAILURE | NPI_TXC_CHANNEL_INVALID(tdc));
153 	}
154 
155 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
156 	    "\nTXC FZC DMC Register Dump for Channel %d\n",
157 	    tdc));
158 
159 	num_regs = sizeof (txc_fzc_dmc_offset) / sizeof (uint64_t);
160 	for (i = 0; i < num_regs; i++) {
161 		offset = TXC_FZC_REG_CN_OFFSET(txc_fzc_dmc_offset[i], tdc);
162 		NXGE_REG_RD64(handle, offset, &value);
163 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
164 		    "%s\t 0x%08llx \n",
165 		    offset, txc_fzc_dmc_name[i], value));
166 	}
167 
168 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
169 	    "\n TXC FZC Register Dump for Channel %d done\n", tdc));
170 
171 	return (NPI_SUCCESS);
172 }
173 
174 /*
175  * npi_txc_dump_fzc_regs
176  * Dumps the contents of txc csrs and fzc registers
177  *
178  *
179  * return:
180  *     NPI_SUCCESS
181  *     NPI_FAILURE
182  *
183  */
184 npi_status_t
185 npi_txc_dump_fzc_regs(npi_handle_t handle)
186 {
187 
188 	uint64_t value;
189 	int num_regs, i;
190 
191 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
192 	    "\nTXC FZC Common Register Dump\n"));
193 
194 	num_regs = sizeof (txc_fzc_offset) / sizeof (uint64_t);
195 	for (i = 0; i < num_regs; i++) {
196 		NXGE_REG_RD64(handle, txc_fzc_offset[i], &value);
197 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
198 		    "%s\t 0x%08llx \n",
199 		    txc_fzc_offset[i], txc_fzc_name[i], value));
200 	}
201 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
202 	    "\n TXC FZC Common Register Dump Done \n"));
203 
204 	return (NPI_SUCCESS);
205 }
206 
207 /*
208  * npi_txc_dump_port_fzc_regs
209  * Dumps the contents of TXC csrs and fzc registers
210  *
211  * Input:
212  *	handle		- NPI handle
213  *         port:      port number
214  *
215  * return:
216  *     NPI_SUCCESS
217  *     NPI_FAILURE
218  *
219  */
220 npi_status_t
221 npi_txc_dump_port_fzc_regs(npi_handle_t handle, uint8_t port)
222 {
223 	uint64_t		value, offset;
224 	int 			num_regs, i;
225 
226 	ASSERT(IS_PORT_NUM_VALID(port));
227 
228 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
229 	    "\nTXC FZC PORT Register Dump for port %d\n", port));
230 
231 	num_regs = sizeof (txc_fzc_port_offset) / sizeof (uint64_t);
232 	for (i = 0; i < num_regs; i++) {
233 		offset = TXC_FZC_REG_PT_OFFSET(txc_fzc_port_offset[i], port);
234 		NXGE_REG_RD64(handle, offset, &value);
235 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
236 		    "%s\t 0x%08llx \n",
237 		    offset, txc_fzc_port_name[i], value));
238 	}
239 
240 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
241 	    "\n TXC FZC Register Dump for port %d done\n", port));
242 
243 	return (NPI_SUCCESS);
244 }
245 
246 /*
247  * npi_txc_dma_max_burst():
248  *	This function is called to configure the max burst bytes.
249  *
250  * Parameters:
251  *	handle		- NPI handle
252  *	op_mode		- OP_GET: get max burst value
253  *			- OP_SET: set max burst value
254  *	channel		- channel number (0 - 23)
255  *	dma_max_burst_p - pointer to store or used for max burst value.
256  * Return:
257  *	NPI_SUCCESS	- If operation is complete successfully.
258  *
259  *	Error:
260  *	NPI_FAILURE	-
261  *		NPI_TXC_OPCODE_INVALID
262  *		NPI_TXC_CHANNEL_INVALID
263  */
264 npi_status_t
265 npi_txc_dma_max_burst(npi_handle_t handle, io_op_t op_mode, uint8_t channel,
266 		uint32_t *dma_max_burst_p)
267 {
268 	uint64_t val;
269 
270 	ASSERT(TXDMA_CHANNEL_VALID(channel));
271 	if (!TXDMA_CHANNEL_VALID(channel)) {
272 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
273 		    " npi_txc_dma_max_burst"
274 		    " Invalid Input: channel <0x%x>",
275 		    channel));
276 		return (NPI_FAILURE | NPI_TXC_CHANNEL_INVALID(channel));
277 	}
278 
279 	switch (op_mode) {
280 	case OP_GET:
281 		TXC_FZC_REG_READ64(handle, TXC_DMA_MAX_BURST_REG, channel,
282 		    &val);
283 		*dma_max_burst_p = (uint32_t)val;
284 		break;
285 
286 	case OP_SET:
287 		TXC_FZC_REG_WRITE64(handle,
288 		    TXC_DMA_MAX_BURST_REG, channel, *dma_max_burst_p);
289 		break;
290 
291 	default:
292 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
293 		    " npi_txc_dma_max_burst"
294 		    " Invalid Input: burst <0x%x>",
295 		    op_mode));
296 		return (NPI_FAILURE | NPI_TXC_OPCODE_INVALID(channel));
297 	}
298 
299 	return (NPI_SUCCESS);
300 }
301 
302 /*
303  * npi_txc_dma_max_burst_set():
304  *	This function is called to set the max burst bytes.
305  *
306  * Parameters:
307  *	handle		- NPI handle
308  *	channel		- channel number (0 - 23)
309  *	max_burst 	- max burst to set
310  * Return:
311  *	NPI_SUCCESS	- If operation is complete successfully.
312  *
313  *	Error:
314  *	NPI_FAILURE	-
315  */
316 npi_status_t
317 npi_txc_dma_max_burst_set(npi_handle_t handle, uint8_t channel,
318 		uint32_t max_burst)
319 {
320 	ASSERT(TXDMA_CHANNEL_VALID(channel));
321 	if (!TXDMA_CHANNEL_VALID(channel)) {
322 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
323 		    " npi_txc_dma_max_burst_set"
324 		    " Invalid Input: channel <0x%x>",
325 		    channel));
326 		return (NPI_FAILURE | NPI_TXC_CHANNEL_INVALID(channel));
327 	}
328 
329 	TXC_FZC_REG_WRITE64(handle, TXC_DMA_MAX_BURST_REG,
330 	    channel, (uint64_t)max_burst);
331 
332 	return (NPI_SUCCESS);
333 }
334 
335 /*
336  * npi_txc_dma_bytes_transmitted():
337  *	This function is called to get # of bytes transmitted by
338  *	DMA (hardware register is cleared on read).
339  *
340  * Parameters:
341  *	handle		- NPI handle
342  *	channel		- channel number (0 - 23)
343  *	dma_bytes_p 	- pointer to store bytes transmitted.
344  * Return:
345  *	NPI_SUCCESS	- If get is complete successfully.
346  *
347  *	Error:
348  *	NPI_FAILURE	-
349  *		NPI_TXC_PORT_INVALID
350  */
351 npi_status_t
352 npi_txc_dma_bytes_transmitted(npi_handle_t handle, uint8_t channel,
353 		uint32_t *dma_bytes_p)
354 {
355 	uint64_t val;
356 
357 	ASSERT(TXDMA_CHANNEL_VALID(channel));
358 	if (!TXDMA_CHANNEL_VALID(channel)) {
359 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
360 		    " npi_txc_dma_bytes_transmitted"
361 		    " Invalid Input: channel %d",
362 		    channel));
363 		return (NPI_FAILURE | NPI_TXC_CHANNEL_INVALID(channel));
364 	}
365 
366 	TXC_FZC_REG_READ64(handle, TXC_DMA_MAX_LENGTH_REG, channel, &val);
367 	*dma_bytes_p = (uint32_t)val;
368 
369 	return (NPI_SUCCESS);
370 }
371 
372 /*
373  * npi_txc_control():
374  *	This function is called to get or set the control register.
375  *
376  * Parameters:
377  *	handle		- NPI handle
378  *	op_mode		- OP_GET: get control register value
379  *			  OP_SET: set control register value
380  *	txc_control_p	- pointer to hardware defined data structure.
381  * Return:
382  *	NPI_SUCCESS	- If operation is complete successfully.
383  *
384  *	Error:
385  *	NPI_FAILURE	-
386  *		NPI_TXC_OPCODE_INVALID
387  *		NPI_TXC_PORT_INVALID
388  */
389 npi_status_t
390 npi_txc_control(npi_handle_t handle, io_op_t op_mode,
391 		p_txc_control_t txc_control_p)
392 {
393 	switch (op_mode) {
394 	case OP_GET:
395 		NXGE_REG_RD64(handle, TXC_CONTROL_REG, &txc_control_p->value);
396 		break;
397 
398 	case OP_SET:
399 		NXGE_REG_WR64(handle, TXC_CONTROL_REG,
400 		    txc_control_p->value);
401 		break;
402 
403 	default:
404 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
405 		    " npi_txc_control"
406 		    " Invalid Input:  control 0x%x",
407 		    op_mode));
408 		return (NPI_FAILURE | NPI_TXC_OPCODE_INVALID(op_mode));
409 	}
410 
411 	return (NPI_SUCCESS);
412 }
413 
414 /*
415  * npi_txc_global_enable():
416  *	This function is called to globally enable TXC.
417  *
418  * Parameters:
419  *	handle		- NPI handle
420  * Return:
421  *	NPI_SUCCESS	- If enable is complete successfully.
422  *
423  *	Error:
424  */
425 npi_status_t
426 npi_txc_global_enable(npi_handle_t handle)
427 {
428 	txc_control_t	cntl;
429 	uint64_t	val;
430 
431 	cntl.value = 0;
432 	cntl.bits.ldw.txc_enabled = 1;
433 
434 	NXGE_REG_RD64(handle, TXC_CONTROL_REG, &val);
435 	NXGE_REG_WR64(handle, TXC_CONTROL_REG, val | cntl.value);
436 
437 	return (NPI_SUCCESS);
438 }
439 
440 /*
441  * npi_txc_global_disable():
442  *	This function is called to globally disable TXC.
443  *
444  * Parameters:
445  *	handle		- NPI handle
446  * Return:
447  *	NPI_SUCCESS	- If disable is complete successfully.
448  *
449  *	Error:
450  */
451 npi_status_t
452 npi_txc_global_disable(npi_handle_t handle)
453 {
454 	txc_control_t	cntl;
455 	uint64_t	val;
456 
457 
458 	cntl.value = 0;
459 	cntl.bits.ldw.txc_enabled = 0;
460 
461 	NXGE_REG_RD64(handle, TXC_CONTROL_REG, &val);
462 	NXGE_REG_WR64(handle, TXC_CONTROL_REG, val | cntl.value);
463 
464 	return (NPI_SUCCESS);
465 }
466 
467 /*
468  * npi_txc_control_clear():
469  *	This function is called to clear all bits.
470  *
471  * Parameters:
472  *	handle		- NPI handle
473  * Return:
474  *	NPI_SUCCESS	- If reset all bits to 0s is complete successfully.
475  *
476  *	Error:
477  */
478 npi_status_t
479 npi_txc_control_clear(npi_handle_t handle, uint8_t port)
480 {
481 	ASSERT(IS_PORT_NUM_VALID(port));
482 
483 	NXGE_REG_WR64(handle, TXC_PORT_CTL_REG, TXC_PORT_CNTL_CLEAR);
484 
485 	return (NPI_SUCCESS);
486 }
487 
488 /*
489  * npi_txc_training_set():
490  *	This function is called to set the debug training vector.
491  *
492  * Parameters:
493  *	handle			- NPI handle
494  *	vector			- training vector to set.
495  * Return:
496  *	NPI_SUCCESS
497  *
498  *	Error:
499  *	NPI_FAILURE		-
500  */
501 npi_status_t
502 npi_txc_training_set(npi_handle_t handle, uint32_t vector)
503 {
504 	NXGE_REG_WR64(handle, TXC_TRAINING_REG, (uint64_t)vector);
505 
506 	return (NPI_SUCCESS);
507 }
508 
509 /*
510  * npi_txc_training_get():
511  *	This function is called to get the debug training vector.
512  *
513  * Parameters:
514  *	handle			- NPI handle
515  *	vector_p		- pointer to store training vector.
516  * Return:
517  *	NPI_SUCCESS
518  *
519  *	Error:
520  *	NPI_FAILURE		-
521  */
522 npi_status_t
523 npi_txc_training_get(npi_handle_t handle, uint32_t *vector_p)
524 {
525 	uint64_t val;
526 
527 	NXGE_REG_RD64(handle, (TXC_TRAINING_REG & TXC_TRAINING_VECTOR_MASK),
528 	    &val);
529 	*vector_p = (uint32_t)val;
530 
531 	return (NPI_SUCCESS);
532 }
533 
534 /*
535  * npi_txc_port_enable():
536  *	This function is called to enable a particular port.
537  *
538  * Parameters:
539  *	handle		- NPI handle
540  *	port		- port number (0 - 3)
541  * Return:
542  *	NPI_SUCCESS	- If port is enabled successfully.
543  *
544  *	Error:
545  *	NPI_FAILURE	-
546  *		NPI_TXC_PORT_INVALID
547  */
548 npi_status_t
549 npi_txc_port_enable(npi_handle_t handle, uint8_t port)
550 {
551 	uint64_t val;
552 
553 	ASSERT(IS_PORT_NUM_VALID(port));
554 
555 	NXGE_REG_RD64(handle, TXC_CONTROL_REG, &val);
556 	NXGE_REG_WR64(handle, TXC_CONTROL_REG, val | (1 << port));
557 
558 	return (NPI_SUCCESS);
559 }
560 
561 /*
562  * npi_txc_port_disable():
563  *	This function is called to disable a particular port.
564  *
565  * Parameters:
566  *	handle		- NPI handle
567  *	port		- port number (0 - 3)
568  * Return:
569  *	NPI_SUCCESS	- If port is disabled successfully.
570  *
571  *	Error:
572  *	NPI_FAILURE	-
573  *		NPI_TXC_PORT_INVALID
574  */
575 npi_status_t
576 npi_txc_port_disable(npi_handle_t handle, uint8_t port)
577 {
578 	uint64_t val;
579 
580 	ASSERT(IS_PORT_NUM_VALID(port));
581 
582 	NXGE_REG_RD64(handle, TXC_CONTROL_REG, &val);
583 	NXGE_REG_WR64(handle, TXC_CONTROL_REG, (val & ~(1 << port)));
584 
585 	return (NPI_SUCCESS);
586 }
587 
588 /*
589  * npi_txc_port_dma_enable():
590  *	This function is called to bind DMA channels (bitmap) to a port.
591  *
592  * Parameters:
593  *	handle			- NPI handle
594  *	port			- port number (0 - 3)
595  *	port_dma_list_bitmap	- channels bitmap
596  *				(1 to bind, 0 - 23 bits one bit/channel)
597  * Return:
598  *	NPI_SUCCESS		- If channels are bound successfully.
599  *
600  *	Error:
601  *	NPI_FAILURE	-
602  *		NPI_TXC_PORT_INVALID
603  */
604 npi_status_t
605 npi_txc_port_dma_enable(npi_handle_t handle, uint8_t port,
606 		uint32_t port_dma_list_bitmap)
607 {
608 
609 	ASSERT(IS_PORT_NUM_VALID(port));
610 
611 	TXC_FZC_CNTL_REG_WRITE64(handle, TXC_PORT_DMA_ENABLE_REG, port,
612 	    port_dma_list_bitmap);
613 	return (NPI_SUCCESS);
614 }
615 
616 npi_status_t
617 npi_txc_port_dma_list_get(npi_handle_t handle, uint8_t port,
618 		uint32_t *port_dma_list_bitmap)
619 {
620 	uint64_t val;
621 
622 	ASSERT(IS_PORT_NUM_VALID(port));
623 
624 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port, &val);
625 	*port_dma_list_bitmap = (uint32_t)(val & TXC_DMA_DMA_LIST_MASK);
626 
627 	return (NPI_SUCCESS);
628 }
629 
630 /*
631  * npi_txc_port_dma_channel_enable():
632  *	This function is called to bind a channel to a port.
633  *
634  * Parameters:
635  *	handle			- NPI handle
636  *	port			- port number (0 - 3)
637  *	channel			- channel number (0 - 23)
638  * Return:
639  *	NPI_SUCCESS		- If channel is bound successfully.
640  *
641  *	Error:
642  *	NPI_FAILURE		-
643  *		NPI_TXC_PORT_INVALID	-
644  */
645 npi_status_t
646 npi_txc_port_dma_channel_enable(npi_handle_t handle, uint8_t port,
647 		uint8_t channel)
648 {
649 	uint64_t val;
650 
651 	ASSERT(IS_PORT_NUM_VALID(port));
652 
653 	ASSERT(TXDMA_CHANNEL_VALID(channel));
654 	if (!TXDMA_CHANNEL_VALID(channel)) {
655 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
656 		    " npi_txc_port_dma_channel_enable"
657 		    " Invalid Input: channel <0x%x>", channel));
658 		return (NPI_FAILURE | NPI_TXC_CHANNEL_INVALID(channel));
659 	}
660 
661 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port, &val);
662 	TXC_FZC_CNTL_REG_WRITE64(handle, TXC_PORT_DMA_ENABLE_REG, port,
663 	    (val | (1 << channel)));
664 
665 	return (NPI_SUCCESS);
666 }
667 
668 /*
669  * npi_txc_port_dma_channel_disable():
670  *	This function is called to unbind a channel to a port.
671  *
672  * Parameters:
673  *	handle			- NPI handle
674  *	port			- port number (0 - 3)
675  *	channel			- channel number (0 - 23)
676  * Return:
677  *	NPI_SUCCESS		- If channel is unbound successfully.
678  *
679  *	Error:
680  *	NPI_FAILURE		-
681  *		NPI_TXC_PORT_INVALID	-
682  */
683 npi_status_t
684 npi_txc_port_dma_channel_disable(npi_handle_t handle, uint8_t port,
685 		uint8_t channel)
686 {
687 	uint64_t val;
688 
689 	ASSERT(IS_PORT_NUM_VALID(port));
690 
691 	ASSERT(TXDMA_CHANNEL_VALID(channel));
692 	if (!TXDMA_CHANNEL_VALID(channel)) {
693 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
694 		    " npi_txc_port_dma_channel_disable"
695 		    " Invalid Input: channel <0x%x>", channel));
696 		return (NPI_FAILURE | NPI_TXC_CHANNEL_INVALID(channel));
697 	}
698 
699 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PORT_DMA_ENABLE_REG, port, &val)
700 	TXC_FZC_CNTL_REG_WRITE64(handle, TXC_PORT_DMA_ENABLE_REG, port,
701 	    val & ~(1 << channel));
702 
703 	return (NPI_SUCCESS);
704 }
705 
706 /*
707  * npi_txc_max_reorder_set():
708  *	This function is called to set the per port reorder resources
709  *
710  * Parameters:
711  *	handle			- NPI handle
712  *	port			- port to set
713  *	reorder			- reorder resources (4 bits)
714  * Return:
715  *	NPI_SUCCESS
716  *
717  *	Error:
718  *	NPI_FAILURE		-
719  */
720 npi_status_t
721 npi_txc_reorder_set(npi_handle_t handle, uint8_t port, uint8_t *reorder)
722 {
723 	uint64_t val;
724 
725 	ASSERT(IS_PORT_NUM_VALID(port));
726 
727 	NXGE_REG_RD64(handle, TXC_MAX_REORDER_REG, &val);
728 
729 	val |= (*reorder << TXC_MAX_REORDER_SHIFT(port));
730 
731 	NXGE_REG_WR64(handle, TXC_MAX_REORDER_REG, val);
732 
733 	return (NPI_SUCCESS);
734 }
735 
736 /*
737  * npi_txc_reorder_get():
738  *	This function is called to get the txc reorder resources.
739  *
740  * Parameters:
741  *	handle			- NPI handle
742  *	port			- port to get
743  *	reorder			- data to be stored at
744  * Return:
745  *	NPI_SUCCESS
746  *
747  *	Error:
748  *	NPI_FAILURE		-
749  */
750 npi_status_t
751 npi_txc_reorder_get(npi_handle_t handle, uint8_t port, uint32_t *reorder)
752 {
753 	uint64_t val;
754 
755 	ASSERT(IS_PORT_NUM_VALID(port));
756 
757 	NXGE_REG_RD64(handle, TXC_MAX_REORDER_REG, &val);
758 
759 	*reorder = (uint8_t)(val >> TXC_MAX_REORDER_SHIFT(port));
760 
761 	return (NPI_SUCCESS);
762 }
763 
764 /*
765  * npi_txc_pkt_stuffed_get():
766  *	This function is called to get total # of packets processed
767  *	by reorder engine and packetAssy engine.
768  *
769  * Parameters:
770  *	handle		- NPI handle
771  *	port		- port number (0 - 3)
772  *	pkt_assy_p 	- packets processed by Assy engine.
773  *	pkt_reorder_p	- packets processed by reorder engine.
774  *
775  * Return:
776  *	NPI_SUCCESS	- If get is complete successfully.
777  *
778  *	Error:
779  *	NPI_FAILURE	-
780  *		NPI_TXC_PORT_INVALID
781  */
782 npi_status_t
783 npi_txc_pkt_stuffed_get(npi_handle_t handle, uint8_t port,
784 		uint32_t *pkt_assy_p, uint32_t *pkt_reorder_p)
785 {
786 	uint64_t		value;
787 
788 	ASSERT(IS_PORT_NUM_VALID(port));
789 
790 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PKT_STUFFED_REG, port, &value);
791 	*pkt_assy_p = ((uint32_t)((value & TXC_PKT_STUFF_PKTASY_MASK) >>
792 	    TXC_PKT_STUFF_PKTASY_SHIFT));
793 	*pkt_reorder_p = ((uint32_t)((value & TXC_PKT_STUFF_REORDER_MASK) >>
794 	    TXC_PKT_STUFF_REORDER_SHIFT));
795 
796 	return (NPI_SUCCESS);
797 }
798 
799 /*
800  * npi_txc_pkt_xmt_to_mac_get():
801  *	This function is called to get total # of packets transmitted
802  *	to the MAC.
803  *
804  * Parameters:
805  *	handle		- NPI handle
806  *	port		- port number (0 - 3)
807  *	mac_bytes_p 	- bytes transmitted to the MAC.
808  *	mac_pkts_p	- packets transmitted to the MAC.
809  *
810  * Return:
811  *	NPI_SUCCESS	- If get is complete successfully.
812  *
813  *	Error:
814  *	NPI_FAILURE	-
815  *	NPI_TXC_PORT_INVALID
816  */
817 npi_status_t
818 npi_txc_pkt_xmt_to_mac_get(npi_handle_t handle, uint8_t port,
819 		uint32_t *mac_bytes_p, uint32_t *mac_pkts_p)
820 {
821 	uint64_t		value;
822 
823 	ASSERT(IS_PORT_NUM_VALID(port));
824 
825 	TXC_FZC_CNTL_REG_READ64(handle, TXC_PKT_XMIT_REG, port, &value);
826 	*mac_pkts_p = ((uint32_t)((value & TXC_PKTS_XMIT_MASK) >>
827 	    TXC_PKTS_XMIT_SHIFT));
828 	*mac_bytes_p = ((uint32_t)((value & TXC_BYTES_XMIT_MASK) >>
829 	    TXC_BYTES_XMIT_SHIFT));
830 
831 	return (NPI_SUCCESS);
832 }
833 
834 /*
835  * npi_txc_get_ro_states():
836  *	This function is called to get TXC's reorder state-machine states.
837  *
838  * Parameters:
839  *	handle		- NPI handle
840  *	port		- port number
841  *	*states		- TXC Re-order states.
842  *
843  * Return:
844  *	NPI_SUCCESS	- If get is complete successfully.
845  *
846  *	Error:
847  *	NPI_FAILURE	-
848  *	NPI_TXC_PORT_INVALID
849  */
850 npi_status_t
851 npi_txc_ro_states_get(npi_handle_t handle, uint8_t port,
852 				txc_ro_states_t *states)
853 {
854 	txc_ro_ctl_t	ctl;
855 	txc_ro_tids_t	tids;
856 	txc_ro_state0_t	s0;
857 	txc_ro_state1_t	s1;
858 	txc_ro_state2_t	s2;
859 	txc_ro_state3_t	s3;
860 	txc_roecc_st_t	ecc;
861 	txc_ro_data0_t	d0;
862 	txc_ro_data1_t	d1;
863 	txc_ro_data2_t	d2;
864 	txc_ro_data3_t	d3;
865 	txc_ro_data4_t	d4;
866 
867 	ASSERT(IS_PORT_NUM_VALID(port));
868 
869 	TXC_FZC_CNTL_REG_READ64(handle, TXC_ROECC_ST_REG, port, &ecc.value);
870 	if ((ecc.bits.ldw.correct_error) || (ecc.bits.ldw.uncorrect_error)) {
871 		TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_DATA0_REG, port,
872 		    &d0.value);
873 		TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_DATA1_REG, port,
874 		    &d1.value);
875 		TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_DATA2_REG, port,
876 		    &d2.value);
877 		TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_DATA3_REG, port,
878 		    &d3.value);
879 		TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_DATA4_REG, port,
880 		    &d4.value);
881 		states->d0.value = d0.value;
882 		states->d1.value = d1.value;
883 		states->d2.value = d2.value;
884 		states->d3.value = d3.value;
885 		states->d4.value = d4.value;
886 
887 		ecc.bits.ldw.ecc_address = 0;
888 		ecc.bits.ldw.correct_error = 0;
889 		ecc.bits.ldw.uncorrect_error = 0;
890 		ecc.bits.ldw.clr_st = 1;
891 		TXC_FZC_CNTL_REG_WRITE64(handle, TXC_ROECC_ST_REG, port,
892 		    ecc.value);
893 	}
894 
895 	TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_CTL_REG, port, &ctl.value);
896 	TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_STATE0_REG, port, &s0.value);
897 	TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_STATE1_REG, port, &s1.value);
898 	TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_STATE2_REG, port, &s2.value);
899 	TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_STATE3_REG, port, &s3.value);
900 	TXC_FZC_CNTL_REG_READ64(handle, TXC_RO_TIDS_REG, port, &tids.value);
901 
902 	states->roecc.value = ctl.value;
903 	states->st0.value = s0.value;
904 	states->st1.value = s1.value;
905 	states->st2.value = s2.value;
906 	states->st3.value = s3.value;
907 	states->ctl.value = ctl.value;
908 	states->tids.value = tids.value;
909 
910 	ctl.bits.ldw.clr_fail_state = 1;
911 	TXC_FZC_CNTL_REG_WRITE64(handle, TXC_RO_CTL_REG, port, ctl.value);
912 
913 	return (NPI_SUCCESS);
914 }
915 
916 npi_status_t
917 npi_txc_ro_ecc_state_clr(npi_handle_t handle, uint8_t port)
918 {
919 	ASSERT(IS_PORT_NUM_VALID(port));
920 
921 	TXC_FZC_CNTL_REG_WRITE64(handle, TXC_ROECC_ST_REG, port, 0);
922 
923 	return (NPI_SUCCESS);
924 }
925 
926 /*
927  * npi_txc_sf_states_get():
928  *	This function is called to get TXC's store-forward state-machine states.
929  *
930  * Parameters:
931  *	handle		- NPI handle
932  *	port		- port number
933  *	states		- TXC Store-forward states
934  *
935  * Return:
936  *	NPI_SUCCESS	- If get is complete successfully.
937  *
938  *	Error:
939  *	NPI_FAILURE	-
940  *	NPI_TXC_PORT_INVALID
941  */
942 npi_status_t
943 npi_txc_sf_states_get(npi_handle_t handle, uint8_t port,
944     txc_sf_states_t *states)
945 {
946 	txc_sfecc_st_t	ecc;
947 	txc_sf_data0_t	d0;
948 	txc_sf_data1_t	d1;
949 	txc_sf_data2_t	d2;
950 	txc_sf_data3_t	d3;
951 	txc_sf_data4_t	d4;
952 
953 	d0.value = 0;
954 	d1.value = 0;
955 	d2.value = 0;
956 	d3.value = 0;
957 	d4.value = 0;
958 
959 	ASSERT(IS_PORT_NUM_VALID(port));
960 
961 	TXC_FZC_CNTL_REG_READ64(handle, TXC_SFECC_ST_REG, port, &ecc.value);
962 	if ((ecc.bits.ldw.correct_error) || (ecc.bits.ldw.uncorrect_error)) {
963 		TXC_FZC_CNTL_REG_READ64(handle, TXC_SF_DATA0_REG, port,
964 		    &d0.value);
965 		TXC_FZC_CNTL_REG_READ64(handle, TXC_SF_DATA1_REG, port,
966 		    &d1.value);
967 		TXC_FZC_CNTL_REG_READ64(handle, TXC_SF_DATA2_REG, port,
968 		    &d2.value);
969 		TXC_FZC_CNTL_REG_READ64(handle, TXC_SF_DATA3_REG, port,
970 		    &d3.value);
971 		TXC_FZC_CNTL_REG_READ64(handle, TXC_SF_DATA4_REG, port,
972 		    &d4.value);
973 		ecc.bits.ldw.ecc_address = 0;
974 		ecc.bits.ldw.correct_error = 0;
975 		ecc.bits.ldw.uncorrect_error = 0;
976 		ecc.bits.ldw.clr_st = 1;
977 		TXC_FZC_CNTL_REG_WRITE64(handle, TXC_SFECC_ST_REG, port,
978 		    ecc.value);
979 	}
980 
981 	states->sfecc.value = ecc.value;
982 	states->d0.value = d0.value;
983 	states->d1.value = d1.value;
984 	states->d2.value = d2.value;
985 	states->d3.value = d3.value;
986 	states->d4.value = d4.value;
987 
988 	return (NPI_SUCCESS);
989 }
990 
991 npi_status_t
992 npi_txc_sf_ecc_state_clr(npi_handle_t handle, uint8_t port)
993 {
994 	ASSERT(IS_PORT_NUM_VALID(port));
995 
996 	TXC_FZC_CNTL_REG_WRITE64(handle, TXC_SFECC_ST_REG, port, 0);
997 
998 	return (NPI_SUCCESS);
999 }
1000 
1001 /*
1002  * npi_txc_global_istatus_get():
1003  *	This function is called to get TXC's global interrupt status.
1004  *
1005  * Parameters:
1006  *	handle		- NPI handle
1007  *	istatus		- TXC global interrupt status
1008  *
1009  * Return:
1010  */
1011 void
1012 npi_txc_global_istatus_get(npi_handle_t handle, txc_int_stat_t *istatus)
1013 {
1014 	txc_int_stat_t	status;
1015 
1016 	NXGE_REG_RD64(handle, TXC_INT_STAT_REG, &status.value);
1017 
1018 	istatus->value = status.value;
1019 }
1020 
1021 /*
1022  * npi_txc_global_istatus_clear():
1023  *	This function is called to clear TXC's global interrupt status.
1024  *
1025  * Parameters:
1026  *	handle		- NPI handle
1027  *	istatus		- TXC global interrupt status
1028  *
1029  * Return:
1030  */
1031 void
1032 npi_txc_global_istatus_clear(npi_handle_t handle, uint64_t istatus)
1033 {
1034 	NXGE_REG_WR64(handle, TXC_INT_STAT_REG, istatus);
1035 }
1036 
1037 void
1038 npi_txc_global_imask_set(npi_handle_t handle, uint8_t portn, uint8_t istatus)
1039 {
1040 	uint64_t val;
1041 
1042 	NXGE_REG_RD64(handle, TXC_INT_MASK_REG, &val);
1043 	switch (portn) {
1044 	case 0:
1045 		val &= 0xFFFFFF00;
1046 		val |= istatus & 0x3F;
1047 		break;
1048 	case 1:
1049 		val &= 0xFFFF00FF;
1050 		val |= (istatus << 8) & 0x3F00;
1051 		break;
1052 	case 2:
1053 		val &= 0xFF00FFFF;
1054 		val |= (istatus << 16) & 0x3F0000;
1055 		break;
1056 	case 3:
1057 		val &= 0x00FFFFFF;
1058 		val |= (istatus << 24) & 0x3F000000;
1059 		break;
1060 	default:
1061 		;
1062 	}
1063 	NXGE_REG_WR64(handle, TXC_INT_MASK_REG, val);
1064 }
1065