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