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_txdma.h>
29#include <npi_tx_rd64.h>
30#include <npi_tx_wr64.h>
31
32#define	TXDMA_WAIT_LOOP		10000
33#define	TXDMA_WAIT_MSEC		5
34
35static npi_status_t npi_txdma_control_reset_wait(npi_handle_t handle,
36	uint8_t channel);
37static npi_status_t npi_txdma_control_stop_wait(npi_handle_t handle,
38	uint8_t channel);
39static npi_status_t npi_txdma_control_resume_wait(npi_handle_t handle,
40	uint8_t channel);
41
42uint64_t tdc_dmc_offset[] = {
43	TX_RNG_CFIG_REG,
44	TX_RING_HDL_REG,
45	TX_RING_KICK_REG,
46	TX_ENT_MSK_REG,
47	TX_CS_REG,
48	TXDMA_MBH_REG,
49	TXDMA_MBL_REG,
50	TX_DMA_PRE_ST_REG,
51	TX_RNG_ERR_LOGH_REG,
52	TX_RNG_ERR_LOGL_REG,
53	TDMC_INTR_DBG_REG,
54	TX_CS_DBG_REG
55};
56
57const char *tdc_dmc_name[] = {
58	"TX_RNG_CFIG_REG",
59	"TX_RING_HDL_REG",
60	"TX_RING_KICK_REG",
61	"TX_ENT_MSK_REG",
62	"TX_CS_REG",
63	"TXDMA_MBH_REG",
64	"TXDMA_MBL_REG",
65	"TX_DMA_PRE_ST_REG",
66	"TX_RNG_ERR_LOGH_REG",
67	"TX_RNG_ERR_LOGL_REG",
68	"TDMC_INTR_DBG_REG",
69	"TX_CS_DBG_REG"
70};
71
72uint64_t tdc_fzc_offset [] = {
73	TX_LOG_PAGE_VLD_REG,
74	TX_LOG_PAGE_MASK1_REG,
75	TX_LOG_PAGE_VAL1_REG,
76	TX_LOG_PAGE_MASK2_REG,
77	TX_LOG_PAGE_VAL2_REG,
78	TX_LOG_PAGE_RELO1_REG,
79	TX_LOG_PAGE_RELO2_REG,
80	TX_LOG_PAGE_HDL_REG
81};
82
83const char *tdc_fzc_name [] = {
84	"TX_LOG_PAGE_VLD_REG",
85	"TX_LOG_PAGE_MASK1_REG",
86	"TX_LOG_PAGE_VAL1_REG",
87	"TX_LOG_PAGE_MASK2_REG",
88	"TX_LOG_PAGE_VAL2_REG",
89	"TX_LOG_PAGE_RELO1_REG",
90	"TX_LOG_PAGE_RELO2_REG",
91	"TX_LOG_PAGE_HDL_REG"
92};
93
94uint64_t tx_fzc_offset[] = {
95	TX_ADDR_MD_REG,
96	TDMC_INJ_PAR_ERR_REG,
97	TDMC_DBG_SEL_REG,
98	TDMC_TRAINING_REG,
99	TXC_PORT_DMA_ENABLE_REG,
100	TXC_DMA_MAX_BURST_REG
101};
102
103const char *tx_fzc_name[] = {
104	"TX_ADDR_MD_REG",
105	"TDMC_INJ_PAR_ERR_REG",
106	"TDMC_DBG_SEL_REG",
107	"TDMC_TRAINING_REG",
108	"TXC_PORT_DMA_ENABLE_REG",
109	"TXC_DMA_MAX_BURST_REG"
110};
111
112#define	NUM_TDC_DMC_REGS	(sizeof (tdc_dmc_offset) / sizeof (uint64_t))
113#define	NUM_TX_FZC_REGS	(sizeof (tx_fzc_offset) / sizeof (uint64_t))
114
115/*
116 * npi_txdma_dump_tdc_regs
117 * Dumps the contents of tdc csrs and fzc registers
118 *
119 * Input:
120 *         tdc:      TX DMA number
121 *
122 * return:
123 *     NPI_SUCCESS
124 *     NPI_FAILURE
125 *     NPI_TXDMA_CHANNEL_INVALID
126 *
127 */
128npi_status_t
129npi_txdma_dump_tdc_regs(npi_handle_t handle, uint8_t tdc)
130{
131
132	uint64_t		value, offset;
133	int 			num_regs, i;
134
135	ASSERT(TXDMA_CHANNEL_VALID(tdc));
136	if (!TXDMA_CHANNEL_VALID(tdc)) {
137		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
138		    "npi_txdma_dump_tdc_regs"
139		    " Invalid TDC number %d \n",
140		    tdc));
141
142		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(tdc));
143	}
144
145	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
146	    "\nTXDMA DMC Register Dump for Channel %d\n",
147	    tdc));
148
149	num_regs = NUM_TDC_DMC_REGS;
150	for (i = 0; i < num_regs; i++) {
151		TXDMA_REG_READ64(handle, tdc_dmc_offset[i], tdc, &value);
152		offset = NXGE_TXDMA_OFFSET(tdc_dmc_offset[i], handle.is_vraddr,
153		    tdc);
154		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
155		    "%s\t 0x%016llx \n",
156		    offset, tdc_dmc_name[i],
157		    value));
158	}
159
160	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
161	    "\n TXDMA Register Dump for Channel %d done\n", tdc));
162
163	return (NPI_SUCCESS);
164}
165
166/*
167 * npi_txdma_dump_fzc_regs
168 * Dumps the contents of tdc csrs and fzc registers
169 *
170 * Input:
171 *         tdc:      TX DMA number
172 *
173 * return:
174 *     NPI_SUCCESS
175 *     NPI_FAILURE
176 *     NPI_TXDMA_CHANNEL_INVALID
177 *
178 */
179npi_status_t
180npi_txdma_dump_fzc_regs(npi_handle_t handle)
181{
182
183	uint64_t value;
184	int num_regs, i;
185
186	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
187	    "\nFZC_DMC Common Register Dump\n"));
188
189	num_regs = NUM_TX_FZC_REGS;
190	for (i = 0; i < num_regs; i++) {
191#if defined(__i386)
192		NXGE_REG_RD64(handle, (uint32_t)tx_fzc_offset[i], &value);
193#else
194		NXGE_REG_RD64(handle, tx_fzc_offset[i], &value);
195#endif
196		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
197		    "%s\t 0x%08llx \n",
198		    tx_fzc_offset[i],
199		    tx_fzc_name[i], value));
200	}
201	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
202	    "\n TXDMA FZC_DMC Register Dump Done \n"));
203
204	return (NPI_SUCCESS);
205}
206
207npi_status_t
208npi_txdma_tdc_regs_zero(npi_handle_t handle, uint8_t tdc)
209{
210	uint64_t		value;
211	int 			num_regs, i;
212
213	ASSERT(TXDMA_CHANNEL_VALID(tdc));
214	if (!TXDMA_CHANNEL_VALID(tdc)) {
215		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
216		    "npi_txdma_tdc_regs_zero"
217		    " InvaliInvalid TDC number %d \n",
218		    tdc));
219		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(tdc));
220	}
221
222	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
223	    "\nTXDMA DMC Register (zero) for Channel %d\n",
224	    tdc));
225
226	num_regs = NUM_TDC_DMC_REGS;
227	value = 0;
228	for (i = 0; i < num_regs; i++) {
229		TXDMA_REG_WRITE64(handle, tdc_dmc_offset[i], tdc, value);
230	}
231
232	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
233	    "\nTXDMA FZC_DMC Register clear for Channel %d\n",
234	    tdc));
235
236	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
237	    "\n TXDMA Register Clear to 0s for Channel %d done\n", tdc));
238
239	return (NPI_SUCCESS);
240}
241
242/*
243 * npi_txdma_address_mode32_set():
244 *	This function is called to only support 32 bit addressing.
245 *
246 * Parameters:
247 *	handle		- NPI handle
248 *	mode_enable	- B_TRUE  (enable 32 bit mode)
249 *			  B_FALSE (disable 32 bit mode)
250 *
251 * Return:
252 *	NPI_SUCCESS		- If set is complete successfully.
253 *
254 *	Error:
255 *	NONE
256 */
257npi_status_t
258npi_txdma_mode32_set(npi_handle_t handle, boolean_t mode_enable)
259{
260	tx_addr_md_t		mode32;
261
262	mode32.value = 0;
263	if (mode_enable) {
264		mode32.bits.ldw.mode32 = 1;
265	} else {
266		mode32.bits.ldw.mode32 = 0;
267	}
268	NXGE_REG_WR64(handle, TX_ADDR_MD_REG, mode32.value);
269
270	return (NPI_SUCCESS);
271}
272
273/*
274 * npi_txdma_log_page_set():
275 *	This function is called to configure a logical page
276 *	(valid bit, mask, value, relocation).
277 *
278 * Parameters:
279 *	handle		- NPI handle
280 *	cfgp		- pointer to NPI defined data structure:
281 *				- page valid
282 * 				- mask
283 *				- value
284 *				- relocation
285 *	channel		- hardware TXDMA channel from 0 to 23.
286 *
287 * Return:
288 *	NPI_SUCCESS		- If configurations are set successfully.
289 *
290 *	Error:
291 *	NPI_FAILURE -
292 *		NPI_TXDMA_CHANNEL_INVALID	-
293 *		NPI_TXDMA_FUNC_INVALID	-
294 *		NPI_TXDMA_PAGE_INVALID	-
295 */
296npi_status_t
297npi_txdma_log_page_set(npi_handle_t handle, uint8_t channel,
298		p_dma_log_page_t cfgp)
299{
300	log_page_vld_t		vld;
301	int			status;
302	uint64_t		val;
303	dma_log_page_t		cfg;
304
305	DMA_LOG_PAGE_FN_VALIDATE(channel, cfgp->page_num, cfgp->func_num,
306	    status);
307	if (status) {
308		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
309		    " npi_txdma_log_page_set"
310		    " npi_status <0x%x>", status));
311		return (status);
312	}
313
314	TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VLD_REG, channel, 0);
315	TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VLD_REG, channel, &val);
316
317	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
318	    "\n==> npi_txdma_log_page_set: WRITE 0 and "
319	    " READ back 0x%llx\n ", val));
320
321	vld.value = 0;
322	TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VLD_REG, channel, &val);
323
324	val &= 0x3;
325	vld.value |= val;
326
327	vld.value = 0;
328	vld.bits.ldw.func = cfgp->func_num;
329
330	if (!cfgp->page_num) {
331		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_MASK1_REG,
332		    channel, (cfgp->mask & DMA_LOG_PAGE_MASK_MASK));
333		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VAL1_REG,
334		    channel, (cfgp->value & DMA_LOG_PAGE_VALUE_MASK));
335		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_RELO1_REG,
336		    channel, (cfgp->reloc & DMA_LOG_PAGE_RELO_MASK));
337	} else {
338		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_MASK2_REG,
339		    channel, (cfgp->mask & DMA_LOG_PAGE_MASK_MASK));
340		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VAL2_REG,
341		    channel, (cfgp->value & DMA_LOG_PAGE_VALUE_MASK));
342		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_RELO2_REG,
343		    channel, (cfgp->reloc & DMA_LOG_PAGE_RELO_MASK));
344	}
345
346	TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VLD_REG, channel,
347	    vld.value | (cfgp->valid << cfgp->page_num));
348
349	NPI_DEBUG_MSG((handle.function, NPI_REG_CTL,
350	    "\n==> npi_txdma_log_page_set: vld value "
351	    " 0x%llx function %d page_valid01 0x%x\n",
352	    vld.value,
353	    vld.bits.ldw.func,
354	    (cfgp->valid << cfgp->page_num)));
355
356
357	cfg.page_num = 0;
358	cfg.func_num = 0;
359	(void) npi_txdma_log_page_get(handle, channel, &cfg);
360	cfg.page_num = 1;
361	(void) npi_txdma_log_page_get(handle, channel, &cfg);
362
363	return (status);
364}
365
366/*
367 * npi_txdma_log_page_get():
368 *	This function is called to get a logical page
369 *	(valid bit, mask, value, relocation).
370 *
371 * Parameters:
372 *	handle		- NPI handle
373 *	cfgp		- Get the following values (NPI defined structure):
374 *				- page valid
375 * 				- mask
376 *				- value
377 *				- relocation
378 *	channel		- hardware TXDMA channel from 0 to 23.
379 *
380 * Return:
381 *	NPI_SUCCESS		- If configurations are read successfully.
382 *
383 *	Error:
384 *	NPI_FAILURE -
385 *		NPI_TXDMA_CHANNEL_INVALID	-
386 *		NPI_TXDMA_FUNC_INVALID	-
387 *		NPI_TXDMA_PAGE_INVALID	-
388 */
389npi_status_t
390npi_txdma_log_page_get(npi_handle_t handle, uint8_t channel,
391		p_dma_log_page_t cfgp)
392{
393	log_page_vld_t		vld;
394	int			status;
395	uint64_t		val;
396
397	DMA_LOG_PAGE_VALIDATE(channel, cfgp->page_num, status);
398	if (status) {
399		NPI_ERROR_MSG((handle.function, NPI_REG_CTL,
400		    " npi_txdma_log_page_get"
401		    " npi_status <0x%x>", status));
402		return (status);
403	}
404
405	vld.value = 0;
406	vld.bits.ldw.func = cfgp->func_num;
407	TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VLD_REG, channel, &val);
408
409	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
410	    "\n==> npi_txdma_log_page_get: read value "
411	    " function %d  value 0x%llx\n",
412	    cfgp->func_num, val));
413
414	vld.value |= val;
415	cfgp->func_num = vld.bits.ldw.func;
416
417	if (!cfgp->page_num) {
418		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_MASK1_REG, channel, &val);
419		cfgp->mask = val & DMA_LOG_PAGE_MASK_MASK;
420		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VAL1_REG, channel, &val);
421		cfgp->value = val & DMA_LOG_PAGE_VALUE_MASK;
422		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_RELO1_REG, channel, &val);
423		cfgp->reloc = val & DMA_LOG_PAGE_RELO_MASK;
424		cfgp->valid = vld.bits.ldw.page0;
425	} else {
426		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_MASK2_REG, channel, &val);
427		cfgp->mask = val & DMA_LOG_PAGE_MASK_MASK;
428		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VAL2_REG, channel, &val);
429		cfgp->value = val & DMA_LOG_PAGE_VALUE_MASK;
430		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_RELO2_REG, channel, &val);
431		cfgp->reloc = val & DMA_LOG_PAGE_RELO_MASK;
432		cfgp->valid = vld.bits.ldw.page1;
433	}
434
435	return (status);
436}
437
438/*
439 * npi_txdma_log_page_handle_set():
440 *	This function is called to program a page handle
441 *	(bits [63:44] of a 64-bit address to generate
442 *	a 64 bit address)
443 *
444 * Parameters:
445 *	handle		- NPI handle
446 *	hdl_p		- pointer to a logical page handle
447 *			  hardware data structure (log_page_hdl_t).
448 *	channel		- hardware TXDMA channel from 0 to 23.
449 *
450 * Return:
451 *	NPI_SUCCESS		- If configurations are set successfully.
452 *
453 *	Error:
454 *	NPI_FAILURE -
455 *		NPI_TXDMA_CHANNEL_INVALID	-
456 *		NPI_TXDMA_FUNC_INVALID	-
457 *		NPI_TXDMA_PAGE_INVALID	-
458 */
459npi_status_t
460npi_txdma_log_page_handle_set(npi_handle_t handle, uint8_t channel,
461		p_log_page_hdl_t hdl_p)
462{
463	int			status = NPI_SUCCESS;
464
465	ASSERT(TXDMA_CHANNEL_VALID(channel));
466	if (!TXDMA_CHANNEL_VALID(channel)) {
467		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
468		    " npi_txdma_log_page_handle_set"
469		    " Invalid Input: channel <0x%x>",
470		    channel));
471		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
472	}
473
474	TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_HDL_REG,
475	    channel, hdl_p->value);
476
477	return (status);
478}
479
480/*
481 * npi_txdma_log_page_config():
482 *	This function is called to IO operations on
483 *	 a logical page to set, get, clear
484 *	valid bit, mask, value, relocation).
485 *
486 * Parameters:
487 *	handle		- NPI handle
488 *	op_mode		- OP_GET, OP_SET, OP_CLEAR
489 *	type		- NPI specific config type
490 *			   TXDMA_LOG_PAGE_MASK
491 *			   TXDMA_LOG_PAGE_VALUE
492 *			   TXDMA_LOG_PAGE_RELOC
493 *			   TXDMA_LOG_PAGE_VALID
494 *			   TXDMA_LOG_PAGE_ALL
495 *	channel		- hardware TXDMA channel from 0 to 23.
496 *	cfgp		- pointer to the NPI config structure.
497 * Return:
498 *	NPI_SUCCESS		- If configurations are read successfully.
499 *
500 *	Error:
501 *	NPI_FAILURE		-
502 *		NPI_TXDMA_OPCODE_INVALID	-
503 *		NPI_TXDMA_CHANNEL_INVALID	-
504 *		NPI_TXDMA_FUNC_INVALID	-
505 *		NPI_TXDMA_PAGE_INVALID	-
506 */
507npi_status_t
508npi_txdma_log_page_config(npi_handle_t handle, io_op_t op_mode,
509		txdma_log_cfg_t type, uint8_t channel,
510		p_dma_log_page_t cfgp)
511{
512	int			status = NPI_SUCCESS;
513	uint64_t		val;
514
515	ASSERT(TXDMA_CHANNEL_VALID(channel));
516	if (!TXDMA_CHANNEL_VALID(channel)) {
517		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
518		    " npi_txdma_log_page_config"
519		    " Invalid Input: channel <0x%x>",
520		    channel));
521		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
522	}
523
524	switch (op_mode) {
525	case OP_GET:
526		switch (type) {
527		case TXDMA_LOG_PAGE_ALL:
528			return (npi_txdma_log_page_get(handle, channel,
529			    cfgp));
530		case TXDMA_LOG_PAGE_MASK:
531			if (!cfgp->page_num) {
532				TX_LOG_REG_READ64(handle, TX_LOG_PAGE_MASK1_REG,
533				    channel, &val);
534				cfgp->mask = val & DMA_LOG_PAGE_MASK_MASK;
535			} else {
536				TX_LOG_REG_READ64(handle, TX_LOG_PAGE_MASK2_REG,
537				    channel, &val);
538				cfgp->mask = val & DMA_LOG_PAGE_MASK_MASK;
539			}
540			break;
541
542		case TXDMA_LOG_PAGE_VALUE:
543			if (!cfgp->page_num) {
544				TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VAL1_REG,
545				    channel, &val);
546				cfgp->value = val & DMA_LOG_PAGE_VALUE_MASK;
547			} else {
548				TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VAL2_REG,
549				    channel, &val);
550				cfgp->value = val & DMA_LOG_PAGE_VALUE_MASK;
551			}
552			break;
553
554		case TXDMA_LOG_PAGE_RELOC:
555			if (!cfgp->page_num) {
556				TX_LOG_REG_READ64(handle, TX_LOG_PAGE_RELO1_REG,
557				    channel, &val);
558				cfgp->reloc = val & DMA_LOG_PAGE_RELO_MASK;
559			} else {
560				TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VAL2_REG,
561				    channel, &val);
562				cfgp->reloc = val & DMA_LOG_PAGE_RELO_MASK;
563			}
564			break;
565
566		default:
567			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
568			    " npi_txdma_log_page_config"
569			    " Invalid Input: pageconfig <0x%x>",
570			    type));
571			return (NPI_FAILURE |
572			    NPI_TXDMA_OPCODE_INVALID(channel));
573		}
574
575		break;
576
577	case OP_SET:
578	case OP_CLEAR:
579		if (op_mode == OP_CLEAR) {
580			cfgp->valid = 0;
581			cfgp->mask = cfgp->func_num = 0;
582			cfgp->value = cfgp->reloc = 0;
583		}
584		switch (type) {
585		case TXDMA_LOG_PAGE_ALL:
586			return (npi_txdma_log_page_set(handle, channel,
587			    cfgp));
588		case TXDMA_LOG_PAGE_MASK:
589			if (!cfgp->page_num) {
590				TX_LOG_REG_WRITE64(handle,
591				    TX_LOG_PAGE_MASK1_REG, channel,
592				    (cfgp->mask & DMA_LOG_PAGE_MASK_MASK));
593			} else {
594				TX_LOG_REG_WRITE64(handle,
595				    TX_LOG_PAGE_MASK2_REG, channel,
596				    (cfgp->mask & DMA_LOG_PAGE_MASK_MASK));
597			}
598			break;
599
600		case TXDMA_LOG_PAGE_VALUE:
601			if (!cfgp->page_num) {
602				TX_LOG_REG_WRITE64(handle,
603				    TX_LOG_PAGE_VAL1_REG, channel,
604				    (cfgp->value & DMA_LOG_PAGE_VALUE_MASK));
605			} else {
606				TX_LOG_REG_WRITE64(handle,
607				    TX_LOG_PAGE_VAL2_REG, channel,
608				    (cfgp->value & DMA_LOG_PAGE_VALUE_MASK));
609			}
610			break;
611
612		case TXDMA_LOG_PAGE_RELOC:
613			if (!cfgp->page_num) {
614				TX_LOG_REG_WRITE64(handle,
615				    TX_LOG_PAGE_RELO1_REG, channel,
616				    (cfgp->reloc & DMA_LOG_PAGE_RELO_MASK));
617			} else {
618				TX_LOG_REG_WRITE64(handle,
619				    TX_LOG_PAGE_RELO2_REG, channel,
620				    (cfgp->reloc & DMA_LOG_PAGE_RELO_MASK));
621			}
622			break;
623
624		default:
625			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
626			    " npi_txdma_log_page_config"
627			    " Invalid Input: pageconfig <0x%x>",
628			    type));
629			return (NPI_FAILURE |
630			    NPI_TXDMA_OPCODE_INVALID(channel));
631		}
632
633		break;
634	default:
635		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
636		    " npi_txdma_log_page_config"
637		    " Invalid Input: op <0x%x>",
638		    op_mode));
639		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
640	}
641
642	return (status);
643}
644
645/*
646 * npi_txdma_log_page_vld_config():
647 *	This function is called to configure the logical
648 *	page valid register.
649 *
650 * Parameters:
651 *	handle		- NPI handle
652 *	op_mode		- OP_GET: get valid page configuration
653 *			  OP_SET: set valid page configuration
654 *			  OP_UPDATE: update valid page configuration
655 *			  OP_CLEAR: reset both valid pages to
656 *			  not defined (0).
657 *	channel		- hardware TXDMA channel from 0 to 23.
658 *	vld_p		- pointer to hardware defined log page valid register.
659 * Return:
660 *	NPI_SUCCESS		- If set is complete successfully.
661 *
662 *	Error:
663 *	NPI_FAILURE -
664 *		NPI_TXDMA_CHANNEL_INVALID -
665 *		NPI_TXDMA_OPCODE_INVALID -
666 */
667npi_status_t
668npi_txdma_log_page_vld_config(npi_handle_t handle, io_op_t op_mode,
669		uint8_t channel, p_log_page_vld_t vld_p)
670{
671	int			status = NPI_SUCCESS;
672	log_page_vld_t		vld;
673
674	ASSERT(TXDMA_CHANNEL_VALID(channel));
675	if (!TXDMA_CHANNEL_VALID(channel)) {
676		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
677		    " npi_txdma_log_page_vld_config"
678		    " Invalid Input: channel <0x%x>",
679		    channel));
680		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
681	}
682
683	switch (op_mode) {
684	case OP_GET:
685		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VLD_REG, channel,
686		    &vld_p->value);
687		break;
688
689	case OP_SET:
690		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VLD_REG,
691		    channel, vld_p->value);
692		break;
693
694	case OP_UPDATE:
695		TX_LOG_REG_READ64(handle, TX_LOG_PAGE_VLD_REG, channel,
696		    &vld.value);
697		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VLD_REG,
698		    channel, vld.value | vld_p->value);
699		break;
700
701	case OP_CLEAR:
702		TX_LOG_REG_WRITE64(handle, TX_LOG_PAGE_VLD_REG,
703		    channel, 0);
704		break;
705
706	default:
707		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
708		    " npi_txdma_log_pag_vld_cofig"
709		    " Invalid Input: pagevld <0x%x>",
710		    op_mode));
711		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
712	}
713
714	return (status);
715}
716
717/*
718 * npi_txdma_channel_reset():
719 *	This function is called to reset a transmit DMA channel.
720 *	(This function is used to reset a channel and reinitialize
721 *	 all other bits except RST_STATE).
722 *
723 * Parameters:
724 *	handle		- NPI handle (virtualization flag must be defined).
725 *	channel		- logical TXDMA channel from 0 to 23.
726 *			  (If virtualization flag is not set, then
727 *			   logical channel is the same as the hardware
728 *			   channel number).
729 *
730 * Return:
731 *	NPI_SUCCESS		- If reset is complete successfully.
732 *
733 *	Error:
734 *	NPI_FAILURE	-
735 *		NPI_TXDMA_CHANNEL_INVALID -
736 *		NPI_TXDMA_RESET_FAILED -
737 */
738npi_status_t
739npi_txdma_channel_reset(npi_handle_t handle, uint8_t channel)
740{
741	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
742	    " npi_txdma_channel_reset"
743	    " RESETTING",
744	    channel));
745	return (npi_txdma_channel_control(handle, TXDMA_RESET, channel));
746}
747
748/*
749 * npi_txdma_channel_init_enable():
750 *	This function is called to start a transmit DMA channel after reset.
751 *
752 * Parameters:
753 *	handle		- NPI handle (virtualization flag must be defined).
754 *	channel		- logical TXDMA channel from 0 to 23.
755 *			  (If virtualization flag is not set, then
756 *			   logical channel is the same as the hardware
757 *			   channel number).
758 * Return:
759 *	NPI_SUCCESS		- If DMA channel is started successfully.
760 *
761 *	Error:
762 *	NPI_FAILURE	-
763 *		NPI_TXDMA_CHANNEL_INVALID -
764 */
765npi_status_t
766npi_txdma_channel_init_enable(npi_handle_t handle, uint8_t channel)
767{
768	return (npi_txdma_channel_control(handle, TXDMA_INIT_START, channel));
769}
770
771/*
772 * npi_txdma_channel_enable():
773 *	This function is called to start a transmit DMA channel.
774 *
775 * Parameters:
776 *	handle		- NPI handle (virtualization flag must be defined).
777 *	channel		- logical TXDMA channel from 0 to 23.
778 *			  (If virtualization flag is not set, then
779 *			   logical channel is the same as the hardware
780 *			   channel number).
781 * Return:
782 *	NPI_SUCCESS		- If DMA channel is stopped successfully.
783 *
784 *	Error:
785 *	NPI_FAILURE	-
786 *		NPI_TXDMA_CHANNEL_INVALID -
787 */
788
789npi_status_t
790npi_txdma_channel_enable(npi_handle_t handle, uint8_t channel)
791{
792	return (npi_txdma_channel_control(handle, TXDMA_START, channel));
793}
794
795/*
796 * npi_txdma_channel_disable():
797 *	This function is called to stop a transmit DMA channel.
798 *
799 * Parameters:
800 *	handle		- NPI handle (virtualization flag must be defined).
801 *	channel		- logical TXDMA channel from 0 to 23.
802 *			  (If virtualization flag is not set, then
803 *			   logical channel is the same as the hardware
804 *			   channel number).
805 * Return:
806 *	NPI_SUCCESS		- If DMA channel is stopped successfully.
807 *
808 *	Error:
809 *	NPI_FAILURE	-
810 *		NPI_TXDMA_CHANNEL_INVALID -
811 *		NPI_TXDMA_STOP_FAILED -
812 */
813npi_status_t
814npi_txdma_channel_disable(npi_handle_t handle, uint8_t channel)
815{
816	return (npi_txdma_channel_control(handle, TXDMA_STOP, channel));
817}
818
819/*
820 * npi_txdma_channel_resume():
821 *	This function is called to restart a transmit DMA channel.
822 *
823 * Parameters:
824 *	handle		- NPI handle (virtualization flag must be defined).
825 *	channel		- logical TXDMA channel from 0 to 23.
826 *			  (If virtualization flag is not set, then
827 *			   logical channel is the same as the hardware
828 *			   channel number).
829 * Return:
830 *	NPI_SUCCESS		- If DMA channel is stopped successfully.
831 *
832 *	Error:
833 *	NPI_FAILURE	-
834 *		NPI_TXDMA_CHANNEL_INVALID -
835 *		NPI_TXDMA_RESUME_FAILED -
836 */
837npi_status_t
838npi_txdma_channel_resume(npi_handle_t handle, uint8_t channel)
839{
840	return (npi_txdma_channel_control(handle, TXDMA_RESUME, channel));
841}
842
843/*
844 * npi_txdma_channel_mmk_clear():
845 *	This function is called to clear MMK bit.
846 *
847 * Parameters:
848 *	handle		- NPI handle (virtualization flag must be defined).
849 *	channel		- logical TXDMA channel from 0 to 23.
850 *			  (If virtualization flag is not set, then
851 *			   logical channel is the same as the hardware
852 *			   channel number).
853 * Return:
854 *	NPI_SUCCESS		- If MMK is reset successfully.
855 *
856 *	Error:
857 *	NPI_FAILURE	-
858 *		NPI_TXDMA_CHANNEL_INVALID -
859 */
860npi_status_t
861npi_txdma_channel_mmk_clear(npi_handle_t handle, uint8_t channel)
862{
863	return (npi_txdma_channel_control(handle, TXDMA_CLEAR_MMK, channel));
864}
865
866/*
867 * npi_txdma_channel_mbox_enable():
868 *	This function is called to enable the mailbox update.
869 *
870 * Parameters:
871 *	handle		- NPI handle (virtualization flag must be defined).
872 *	channel		- logical TXDMA channel from 0 to 23.
873 *			  (If virtualization flag is not set, then
874 *			   logical channel is the same as the hardware
875 *			   channel number).
876 * Return:
877 *	NPI_SUCCESS		- If mailbox is enabled successfully.
878 *
879 *	Error:
880 *	NPI_HW_ERROR		-
881 *	NPI_FAILURE	-
882 *		NPI_TXDMA_CHANNEL_INVALID -
883 */
884npi_status_t
885npi_txdma_channel_mbox_enable(npi_handle_t handle, uint8_t channel)
886{
887	return (npi_txdma_channel_control(handle, TXDMA_MBOX_ENABLE, channel));
888}
889
890/*
891 * npi_txdma_channel_control():
892 *	This function is called to control a transmit DMA channel
893 *	for reset, start or stop.
894 *
895 * Parameters:
896 *	handle		- NPI handle (virtualization flag must be defined).
897 *	control		- NPI defined control type supported
898 *				- TXDMA_INIT_RESET
899 * 				- TXDMA_INIT_START
900 *				- TXDMA_RESET
901 *				- TXDMA_START
902 *				- TXDMA_STOP
903 *	channel		- logical TXDMA channel from 0 to 23.
904 *			  (If virtualization flag is not set, then
905 *			   logical channel is the same as the hardware
906 *
907 * Return:
908 *	NPI_SUCCESS		- If reset is complete successfully.
909 *
910 *	Error:
911 *	NPI_FAILURE		-
912 *		NPI_TXDMA_OPCODE_INVALID	-
913 *		NPI_TXDMA_CHANNEL_INVALID	-
914 *		NPI_TXDMA_RESET_FAILED	-
915 *		NPI_TXDMA_STOP_FAILED	-
916 *		NPI_TXDMA_RESUME_FAILED	-
917 */
918npi_status_t
919npi_txdma_channel_control(npi_handle_t handle, txdma_cs_cntl_t control,
920		uint8_t channel)
921{
922	int		status = NPI_SUCCESS;
923	tx_cs_t		cs;
924
925	ASSERT(TXDMA_CHANNEL_VALID(channel));
926	if (!TXDMA_CHANNEL_VALID(channel)) {
927		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
928		    " npi_txdma_channel_control"
929		    " Invalid Input: channel <0x%x>",
930		    channel));
931		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
932	}
933
934	switch (control) {
935	case TXDMA_INIT_RESET:
936		cs.value = 0;
937		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs.value);
938		cs.bits.ldw.rst = 1;
939		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
940		return (npi_txdma_control_reset_wait(handle, channel));
941
942	case TXDMA_INIT_START:
943		cs.value = 0;
944		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
945		break;
946
947	case TXDMA_RESET:
948		/*
949		 * Sets reset bit only (Hardware will reset all
950		 * the RW bits but leave the RO bits alone.
951		 */
952		cs.value = 0;
953		cs.bits.ldw.rst = 1;
954		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
955		return (npi_txdma_control_reset_wait(handle, channel));
956
957	case TXDMA_START:
958		/* Enable the DMA channel */
959		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs.value);
960		cs.bits.ldw.stop_n_go = 0;
961		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
962		break;
963
964	case TXDMA_STOP:
965		/* Disable the DMA channel */
966		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs.value);
967		cs.bits.ldw.stop_n_go = 1;
968		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
969		status = npi_txdma_control_stop_wait(handle, channel);
970		if (status) {
971			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
972			    "Cannot stop channel %d (TXC hung!)",
973			    channel));
974		}
975		break;
976
977	case TXDMA_RESUME:
978		/* Resume the packet transmission after stopping */
979		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs.value);
980		cs.value |= ~TX_CS_STOP_N_GO_MASK;
981		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
982		return (npi_txdma_control_resume_wait(handle, channel));
983
984	case TXDMA_CLEAR_MMK:
985		/* Write 1 to MK bit to clear the MMK bit */
986		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs.value);
987		cs.bits.ldw.mk = 1;
988		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
989		break;
990
991	case TXDMA_MBOX_ENABLE:
992		/*
993		 * Write 1 to MB bit to enable mailbox update
994		 * (cleared to 0 by hardware after update).
995		 */
996		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs.value);
997		cs.bits.ldw.mb = 1;
998		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs.value);
999		break;
1000
1001	default:
1002		status =  (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
1003		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1004		    " npi_txdma_channel_control"
1005		    " Invalid Input: control <0x%x>",
1006		    control));
1007	}
1008
1009	return (status);
1010}
1011
1012/*
1013 * npi_txdma_control_status():
1014 *	This function is called to operate on the control
1015 *	and status register.
1016 *
1017 * Parameters:
1018 *	handle		- NPI handle
1019 *	op_mode		- OP_GET: get hardware control and status
1020 *			  OP_SET: set hardware control and status
1021 *			  OP_UPDATE: update hardware control and status.
1022 *			  OP_CLEAR: clear control and status register to 0s.
1023 *	channel		- hardware TXDMA channel from 0 to 23.
1024 *	cs_p		- pointer to hardware defined control and status
1025 *			  structure.
1026 * Return:
1027 *	NPI_SUCCESS		- If set is complete successfully.
1028 *
1029 *	Error:
1030 *	NPI_FAILURE		-
1031 *		NPI_TXDMA_OPCODE_INVALID	-
1032 *		NPI_TXDMA_CHANNEL_INVALID	-
1033 *		NPI_TXDMA_FUNC_INVALID	-
1034 */
1035npi_status_t
1036npi_txdma_control_status(npi_handle_t handle, io_op_t op_mode,
1037		uint8_t channel, p_tx_cs_t cs_p)
1038{
1039	int		status = NPI_SUCCESS;
1040	tx_cs_t		txcs;
1041
1042	ASSERT(TXDMA_CHANNEL_VALID(channel));
1043	if (!TXDMA_CHANNEL_VALID(channel)) {
1044		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1045		    " npi_txdma_control_status"
1046		    " Invalid Input: channel <0x%x>",
1047		    channel));
1048		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1049	}
1050
1051	switch (op_mode) {
1052	case OP_GET:
1053		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &cs_p->value);
1054		break;
1055
1056	case OP_SET:
1057		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel, cs_p->value);
1058		break;
1059
1060	case OP_UPDATE:
1061		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &txcs.value);
1062		TXDMA_REG_WRITE64(handle, TX_CS_REG, channel,
1063		    cs_p->value | txcs.value);
1064		break;
1065
1066	default:
1067		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1068		    " npi_txdma_control_status"
1069		    " Invalid Input: control <0x%x>",
1070		    op_mode));
1071		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
1072	}
1073
1074	return (status);
1075
1076}
1077
1078/*
1079 * npi_txdma_event_mask():
1080 *	This function is called to operate on the event mask
1081 *	register which is used for generating interrupts..
1082 *	and status register.
1083 *
1084 * Parameters:
1085 *	handle		- NPI handle
1086 *	op_mode		- OP_GET: get hardware event mask
1087 *			  OP_SET: set hardware interrupt event masks
1088 *			  OP_CLEAR: clear control and status register to 0s.
1089 *	channel		- hardware TXDMA channel from 0 to 23.
1090 *	mask_p		- pointer to hardware defined event mask
1091 *			  structure.
1092 * Return:
1093 *	NPI_SUCCESS		- If set is complete successfully.
1094 *
1095 *	Error:
1096 *	NPI_FAILURE		-
1097 *		NPI_TXDMA_OPCODE_INVALID	-
1098 *		NPI_TXDMA_CHANNEL_INVALID	-
1099 */
1100npi_status_t
1101npi_txdma_event_mask(npi_handle_t handle, io_op_t op_mode,
1102		uint8_t channel, p_tx_dma_ent_msk_t mask_p)
1103{
1104	int			status = NPI_SUCCESS;
1105	tx_dma_ent_msk_t	mask;
1106
1107	ASSERT(TXDMA_CHANNEL_VALID(channel));
1108	if (!TXDMA_CHANNEL_VALID(channel)) {
1109		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1110		    " npi_txdma_event_mask"
1111		    " Invalid Input: channel <0x%x>",
1112		    channel));
1113		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1114	}
1115
1116	switch (op_mode) {
1117	case OP_GET:
1118		TXDMA_REG_READ64(handle, TX_ENT_MSK_REG, channel,
1119		    &mask_p->value);
1120		break;
1121
1122	case OP_SET:
1123		TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1124		    mask_p->value);
1125		break;
1126
1127	case OP_UPDATE:
1128		TXDMA_REG_READ64(handle, TX_ENT_MSK_REG, channel, &mask.value);
1129		TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1130		    mask_p->value | mask.value);
1131		break;
1132
1133	default:
1134		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1135		    " npi_txdma_event_mask"
1136		    " Invalid Input: eventmask <0x%x>",
1137		    op_mode));
1138		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
1139	}
1140
1141	return (status);
1142}
1143
1144/*
1145 * npi_txdma_event_mask_config():
1146 *	This function is called to operate on the event mask
1147 *	register which is used for generating interrupts..
1148 *	and status register.
1149 *
1150 * Parameters:
1151 *	handle		- NPI handle
1152 *	op_mode		- OP_GET: get hardware event mask
1153 *			  OP_SET: set hardware interrupt event masks
1154 *			  OP_CLEAR: clear control and status register to 0s.
1155 *	channel		- hardware TXDMA channel from 0 to 23.
1156 *	cfgp		- pointer to NPI defined event mask
1157 *			  enum data type.
1158 * Return:
1159 *	NPI_SUCCESS		- If set is complete successfully.
1160 *
1161 *	Error:
1162 *	NPI_FAILURE		-
1163 *		NPI_TXDMA_OPCODE_INVALID	-
1164 *		NPI_TXDMA_CHANNEL_INVALID	-
1165 */
1166npi_status_t
1167npi_txdma_event_mask_config(npi_handle_t handle, io_op_t op_mode,
1168		uint8_t channel, txdma_ent_msk_cfg_t *mask_cfgp)
1169{
1170	int		status = NPI_SUCCESS;
1171	uint64_t	configuration = *mask_cfgp;
1172	uint64_t	value;
1173
1174	ASSERT(TXDMA_CHANNEL_VALID(channel));
1175	if (!TXDMA_CHANNEL_VALID(channel)) {
1176		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1177		    " npi_txdma_event_mask_config"
1178		    " Invalid Input: channel <0x%x>",
1179		    channel));
1180
1181		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1182	}
1183
1184	switch (op_mode) {
1185	case OP_GET:
1186		TXDMA_REG_READ64(handle, TX_ENT_MSK_REG, channel,
1187		    (uint64_t *)mask_cfgp);
1188		break;
1189
1190	case OP_SET:
1191		TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1192		    configuration);
1193		break;
1194
1195	case OP_UPDATE:
1196		TXDMA_REG_READ64(handle, TX_ENT_MSK_REG, channel, &value);
1197		TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1198		    configuration | value);
1199		break;
1200
1201	case OP_CLEAR:
1202		TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1203		    CFG_TXDMA_MASK_ALL);
1204		break;
1205	default:
1206		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1207		    " npi_txdma_event_mask_config"
1208		    " Invalid Input: eventmask <0x%x>",
1209		    op_mode));
1210		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
1211	}
1212
1213	return (status);
1214}
1215
1216/*
1217 * npi_txdma_event_mask_mk_out():
1218 *	This function is called to mask out the packet transmit marked event.
1219 *
1220 * Parameters:
1221 *	handle		- NPI handle
1222 *	channel		- hardware TXDMA channel from 0 to 23.
1223 *			  enum data type.
1224 * Return:
1225 *	NPI_SUCCESS		- If set is complete successfully.
1226 *
1227 *	Error:
1228 *	NPI_FAILURE		-
1229 *		NPI_TXDMA_CHANNEL_INVALID	-
1230 */
1231npi_status_t
1232npi_txdma_event_mask_mk_out(npi_handle_t handle, uint8_t channel)
1233{
1234	uint64_t event_mask;
1235	int	status = NPI_SUCCESS;
1236
1237	ASSERT(TXDMA_CHANNEL_VALID(channel));
1238	if (!TXDMA_CHANNEL_VALID(channel)) {
1239		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1240		    " npi_txdma_event_mask_mk_out"
1241		    " Invalid Input: channel <0x%x>",
1242		    channel));
1243		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1244	}
1245
1246	TXDMA_REG_READ64(handle, TX_ENT_MSK_REG, channel, &event_mask);
1247	TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1248	    event_mask & (~TX_ENT_MSK_MK_MASK));
1249
1250	return (status);
1251}
1252
1253/*
1254 * npi_txdma_event_mask_mk_in():
1255 *	This function is called to set the mask for the the packet marked event.
1256 *
1257 * Parameters:
1258 *	handle		- NPI handle
1259 *	channel		- hardware TXDMA channel from 0 to 23.
1260 *			  enum data type.
1261 * Return:
1262 *	NPI_SUCCESS		- If set is complete successfully.
1263 *
1264 *	Error:
1265 *	NPI_FAILURE		-
1266 *		NPI_TXDMA_CHANNEL_INVALID	-
1267 */
1268npi_status_t
1269npi_txdma_event_mask_mk_in(npi_handle_t handle, uint8_t channel)
1270{
1271	uint64_t event_mask;
1272	int	status = NPI_SUCCESS;
1273
1274	ASSERT(TXDMA_CHANNEL_VALID(channel));
1275	if (!TXDMA_CHANNEL_VALID(channel)) {
1276		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1277		    " npi_txdma_event_mask_mk_in"
1278		    " Invalid Input: channel <0x%x>",
1279		    channel));
1280		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1281	}
1282
1283	TXDMA_REG_READ64(handle, TX_ENT_MSK_REG, channel, &event_mask);
1284	TXDMA_REG_WRITE64(handle, TX_ENT_MSK_REG, channel,
1285	    event_mask | TX_ENT_MSK_MK_MASK);
1286
1287	return (status);
1288}
1289
1290/*
1291 * npi_txdma_ring_addr_set():
1292 *	This function is called to configure the transmit descriptor
1293 *	ring address and its size.
1294 *
1295 * Parameters:
1296 *	handle		- NPI handle (virtualization flag must be defined
1297 *			  if its register pointer is from the virtual region).
1298 *	channel		- logical TXDMA channel from 0 to 23.
1299 *			  (If virtualization flag is not set, then
1300 *			   logical channel is the same as the hardware
1301 *			   channel number).
1302 *	start_addr	- starting address of the descriptor
1303 *	len		- maximum length of the descriptor
1304 *			  (in number of 64 bytes block).
1305 * Return:
1306 *	NPI_SUCCESS		- If set is complete successfully.
1307 *
1308 *	Error:
1309 *	NPI_FAILURE		-
1310 *		NPI_TXDMA_OPCODE_INVALID	-
1311 *		NPI_TXDMA_CHANNEL_INVALID	-
1312 */
1313npi_status_t
1314npi_txdma_ring_addr_set(npi_handle_t handle, uint8_t channel,
1315		uint64_t start_addr, uint32_t len)
1316{
1317	int		status = NPI_SUCCESS;
1318	tx_rng_cfig_t	cfg;
1319
1320	ASSERT(TXDMA_CHANNEL_VALID(channel));
1321	if (!TXDMA_CHANNEL_VALID(channel)) {
1322		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1323		    " npi_txdma_ring_addr_set"
1324		    " Invalid Input: channel <0x%x>",
1325		    channel));
1326		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1327	}
1328
1329	cfg.value = ((start_addr & TX_RNG_CFIG_ADDR_MASK) |
1330	    (((uint64_t)len) << TX_RNG_CFIG_LEN_SHIFT));
1331	TXDMA_REG_WRITE64(handle, TX_RNG_CFIG_REG, channel, cfg.value);
1332
1333	return (status);
1334}
1335
1336/*
1337 * npi_txdma_ring_config():
1338 *	This function is called to config a descriptor ring
1339 *	by using the hardware defined data.
1340 *
1341 * Parameters:
1342 *	handle		- NPI handle (virtualization flag must be defined
1343 *			  if its register pointer is from the virtual region).
1344 *	channel		- logical TXDMA channel from 0 to 23.
1345 *			  (If virtualization flag is not set, then
1346 *			   logical channel is the same as the hardware
1347 *			   channel number).
1348 *	op_mode		- OP_GET: get transmit ring configuration
1349 *			  OP_SET: set transmit ring configuration
1350 *	reg_data	- pointer to hardware defined transmit ring
1351 *			  configuration data structure.
1352 * Return:
1353 *	NPI_SUCCESS		- If set/get is complete successfully.
1354 *
1355 *	Error:
1356 *	NPI_FAILURE		-
1357 *		NPI_TXDMA_CHANNEL_INVALID	-
1358 */
1359npi_status_t
1360npi_txdma_ring_config(npi_handle_t handle, io_op_t op_mode,
1361		uint8_t channel, uint64_t *reg_data)
1362{
1363	int		status = NPI_SUCCESS;
1364
1365	ASSERT(TXDMA_CHANNEL_VALID(channel));
1366	if (!TXDMA_CHANNEL_VALID(channel)) {
1367		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1368		    " npi_txdma_ring_config"
1369		    " Invalid Input: channel <0x%x>",
1370		    channel));
1371		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1372	}
1373
1374	switch (op_mode) {
1375	case OP_GET:
1376		TXDMA_REG_READ64(handle, TX_RNG_CFIG_REG, channel, reg_data);
1377		break;
1378
1379	case OP_SET:
1380		TXDMA_REG_WRITE64(handle, TX_RNG_CFIG_REG, channel,
1381		    *reg_data);
1382		break;
1383
1384	default:
1385		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1386		    " npi_txdma_ring_config"
1387		    " Invalid Input: ring_config <0x%x>",
1388		    op_mode));
1389		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
1390	}
1391
1392	return (status);
1393}
1394
1395/*
1396 * npi_txdma_mbox_config():
1397 *	This function is called to config the mailbox address
1398 *
1399 * Parameters:
1400 *	handle		- NPI handle (virtualization flag must be defined
1401 *			  if its register pointer is from the virtual region).
1402 *	channel		- logical TXDMA channel from 0 to 23.
1403 *			  (If virtualization flag is not set, then
1404 *			   logical channel is the same as the hardware
1405 *			   channel number).
1406 *	op_mode		- OP_GET: get the mailbox address
1407 *			  OP_SET: set the mailbox address
1408 *	reg_data	- pointer to the mailbox address.
1409 * Return:
1410 *	NPI_SUCCESS		- If set is complete successfully.
1411 *
1412 *	Error:
1413 *	NPI_FAILURE		-
1414 *		NPI_TXDMA_OPCODE_INVALID	-
1415 *		NPI_TXDMA_CHANNEL_INVALID	-
1416 */
1417npi_status_t
1418npi_txdma_mbox_config(npi_handle_t handle, io_op_t op_mode,
1419		uint8_t channel, uint64_t *mbox_addr)
1420{
1421	int		status = NPI_SUCCESS;
1422	txdma_mbh_t	mh;
1423	txdma_mbl_t	ml;
1424
1425	ASSERT(TXDMA_CHANNEL_VALID(channel));
1426	if (!TXDMA_CHANNEL_VALID(channel)) {
1427		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1428		    " npi_txdma_mbox_config"
1429		    " Invalid Input: channel <0x%x>",
1430		    channel));
1431		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1432	}
1433
1434	mh.value = ml.value = 0;
1435
1436	switch (op_mode) {
1437	case OP_GET:
1438		TXDMA_REG_READ64(handle, TXDMA_MBH_REG, channel, &mh.value);
1439		TXDMA_REG_READ64(handle, TXDMA_MBL_REG, channel, &ml.value);
1440		*mbox_addr = ml.value;
1441		*mbox_addr |= (mh.value << TXDMA_MBH_ADDR_SHIFT);
1442
1443		break;
1444
1445	case OP_SET:
1446		ml.bits.ldw.mbaddr = ((*mbox_addr & TXDMA_MBL_MASK) >>
1447		    TXDMA_MBL_SHIFT);
1448		TXDMA_REG_WRITE64(handle, TXDMA_MBL_REG, channel, ml.value);
1449		mh.bits.ldw.mbaddr = ((*mbox_addr >> TXDMA_MBH_ADDR_SHIFT) &
1450		    TXDMA_MBH_MASK);
1451		TXDMA_REG_WRITE64(handle, TXDMA_MBH_REG, channel, mh.value);
1452
1453		break;
1454
1455	default:
1456		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1457		    " npi_txdma_mbox_config"
1458		    " Invalid Input: mbox <0x%x>",
1459		    op_mode));
1460		return (NPI_FAILURE | NPI_TXDMA_OPCODE_INVALID(channel));
1461	}
1462
1463	return (status);
1464
1465}
1466
1467/*
1468 * npi_txdma_desc_gather_set():
1469 *	This function is called to set up a transmit descriptor entry.
1470 *
1471 * Parameters:
1472 *	handle		- NPI handle (register pointer is the
1473 *			  descriptor address in memory).
1474 *	desc_p		- pointer to a descriptor
1475 *	gather_index	- which entry (starts from index 0 to 15)
1476 *	mark		- mark bit (only valid if it is the first gather).
1477 *	ngathers	- number of gather pointers to set to the first gather.
1478 *	dma_ioaddr	- starting dma address of an IO buffer to write.
1479 *			  (SAD)
1480 *	transfer_len	- transfer len.
1481 * Return:
1482 *	NPI_SUCCESS		- If set is complete successfully.
1483 *
1484 *	Error:
1485 *	NPI_FAILURE		-
1486 *		NPI_TXDMA_OPCODE_INVALID	-
1487 *		NPI_TXDMA_CHANNEL_INVALID	-
1488 *		NPI_TXDMA_XFER_LEN_INVALID	-
1489 */
1490npi_status_t
1491npi_txdma_desc_gather_set(npi_handle_t handle,
1492		p_tx_desc_t desc_p, uint8_t gather_index,
1493		boolean_t mark, uint8_t ngathers,
1494		uint64_t dma_ioaddr, uint32_t transfer_len)
1495{
1496	int		status;
1497
1498	status = NPI_TXDMA_GATHER_INDEX(gather_index);
1499	if (status) {
1500		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1501		    " npi_txdma_desc_gather_set"
1502		    " Invalid Input: gather_index <0x%x>",
1503		    gather_index));
1504		return (status);
1505	}
1506
1507	if (transfer_len > TX_MAX_TRANSFER_LENGTH) {
1508		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1509		    " npi_txdma_desc_gather_set"
1510		    " Invalid Input: tr_len <0x%x>",
1511		    transfer_len));
1512		return (NPI_FAILURE | NPI_TXDMA_XFER_LEN_INVALID);
1513	}
1514
1515	if (gather_index == 0) {
1516		desc_p->bits.hdw.sop = 1;
1517		desc_p->bits.hdw.mark = mark;
1518		desc_p->bits.hdw.num_ptr = ngathers;
1519		NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1520		    "npi_txdma_gather_set: SOP len %d (%d)",
1521		    desc_p->bits.hdw.tr_len, transfer_len));
1522	}
1523
1524	desc_p->bits.hdw.tr_len = transfer_len;
1525	desc_p->bits.hdw.sad = dma_ioaddr >> 32;
1526	desc_p->bits.ldw.sad = dma_ioaddr & 0xffffffff;
1527
1528	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1529	    "npi_txdma_gather_set: xfer len %d to set (%d)",
1530	    desc_p->bits.hdw.tr_len, transfer_len));
1531
1532	NXGE_MEM_PIO_WRITE64(handle, desc_p->value);
1533
1534	return (status);
1535}
1536
1537/*
1538 * npi_txdma_desc_sop_set():
1539 *	This function is called to set up the first gather entry.
1540 *
1541 * Parameters:
1542 *	handle		- NPI handle (register pointer is the
1543 *			  descriptor address in memory).
1544 *	desc_p		- pointer to a descriptor
1545 *	mark		- mark bit (only valid if it is the first gather).
1546 *	ngathers	- number of gather pointers to set to the first gather.
1547 * Return:
1548 *	NPI_SUCCESS		- If set is complete successfully.
1549 *
1550 *	Error:
1551 */
1552npi_status_t
1553npi_txdma_desc_gather_sop_set(npi_handle_t handle,
1554		p_tx_desc_t desc_p,
1555		boolean_t mark_mode,
1556		uint8_t ngathers)
1557{
1558	int		status = NPI_SUCCESS;
1559
1560	desc_p->bits.hdw.sop = 1;
1561	desc_p->bits.hdw.mark = mark_mode;
1562	desc_p->bits.hdw.num_ptr = ngathers;
1563
1564	NXGE_MEM_PIO_WRITE64(handle, desc_p->value);
1565
1566	return (status);
1567}
1568npi_status_t
1569npi_txdma_desc_gather_sop_set_1(npi_handle_t handle,
1570		p_tx_desc_t desc_p,
1571		boolean_t mark_mode,
1572		uint8_t ngathers,
1573		uint32_t extra)
1574{
1575	int		status = NPI_SUCCESS;
1576
1577	desc_p->bits.hdw.sop = 1;
1578	desc_p->bits.hdw.mark = mark_mode;
1579	desc_p->bits.hdw.num_ptr = ngathers;
1580	desc_p->bits.hdw.tr_len += extra;
1581
1582	NXGE_MEM_PIO_WRITE64(handle, desc_p->value);
1583
1584	return (status);
1585}
1586
1587npi_status_t
1588npi_txdma_desc_set_xfer_len(npi_handle_t handle,
1589		p_tx_desc_t desc_p,
1590		uint32_t transfer_len)
1591{
1592	int		status = NPI_SUCCESS;
1593
1594	desc_p->bits.hdw.tr_len = transfer_len;
1595
1596	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1597	    "npi_set_xfer_len: len %d (%d)",
1598	    desc_p->bits.hdw.tr_len, transfer_len));
1599
1600	NXGE_MEM_PIO_WRITE64(handle, desc_p->value);
1601
1602	return (status);
1603}
1604
1605npi_status_t
1606npi_txdma_desc_set_zero(npi_handle_t handle, uint16_t entries)
1607{
1608	uint32_t	offset;
1609	int		i;
1610
1611	/*
1612	 * Assume no wrapped around.
1613	 */
1614	offset = 0;
1615	for (i = 0; i < entries; i++) {
1616		NXGE_REG_WR64(handle, offset, 0);
1617		offset += (i * TXDMA_DESC_SIZE);
1618	}
1619
1620	return (NPI_SUCCESS);
1621}
1622
1623npi_status_t
1624npi_txdma_desc_mem_get(npi_handle_t handle, uint16_t index,
1625		p_tx_desc_t desc_p)
1626{
1627	int		status = NPI_SUCCESS;
1628
1629	npi_txdma_dump_desc_one(handle, desc_p, index);
1630
1631	return (status);
1632
1633}
1634
1635/*
1636 * npi_txdma_desc_kick_reg_set():
1637 *	This function is called to kick the transmit  to start transmission.
1638 *
1639 * Parameters:
1640 *	handle		- NPI handle (virtualization flag must be defined).
1641 *	channel		- logical TXDMA channel from 0 to 23.
1642 *			  (If virtualization flag is not set, then
1643 *			   logical channel is the same as the hardware
1644 *			   channel number).
1645 *	tail_index	- index into the transmit descriptor
1646 *	wrap		- toggle bit to indicate if the tail index is
1647 *			  wrapped around.
1648 *
1649 * Return:
1650 *	NPI_SUCCESS		- If set is complete successfully.
1651 *
1652 *	Error:
1653 *	NPI_FAILURE		-
1654 *		NPI_TXDMA_CHANNEL_INVALID	-
1655 */
1656npi_status_t
1657npi_txdma_desc_kick_reg_set(npi_handle_t handle, uint8_t channel,
1658		uint16_t tail_index, boolean_t wrap)
1659{
1660	int			status = NPI_SUCCESS;
1661	tx_ring_kick_t		kick;
1662
1663	ASSERT(TXDMA_CHANNEL_VALID(channel));
1664	if (!TXDMA_CHANNEL_VALID(channel)) {
1665		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1666		    " npi_txdma_desc_kick_reg_set"
1667		    " Invalid Input: channel <0x%x>",
1668		    channel));
1669		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1670	}
1671
1672	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1673	    " npi_txdma_desc_kick_reg_set: "
1674	    " KICKING channel %d",
1675	    channel));
1676
1677	/* Toggle the wrap around bit */
1678	kick.value = 0;
1679	kick.bits.ldw.wrap = wrap;
1680	kick.bits.ldw.tail = tail_index;
1681
1682	/* Kick start the Transmit kick register */
1683	TXDMA_REG_WRITE64(handle, TX_RING_KICK_REG, channel, kick.value);
1684
1685	return (status);
1686}
1687
1688/*
1689 * npi_txdma_desc_kick_reg_get():
1690 *	This function is called to kick the transmit  to start transmission.
1691 *
1692 * Parameters:
1693 *	handle		- NPI handle (virtualization flag must be defined).
1694 *	channel		- logical TXDMA channel from 0 to 23.
1695 *			  (If virtualization flag is not set, then
1696 *			   logical channel is the same as the hardware
1697 *			   channel number).
1698 *	tail_index	- index into the transmit descriptor
1699 *	wrap		- toggle bit to indicate if the tail index is
1700 *			  wrapped around.
1701 *
1702 * Return:
1703 *	NPI_SUCCESS		- If get is complete successfully.
1704 *
1705 *	Error:
1706 *	NPI_FAILURE		-
1707 *		NPI_TXDMA_CHANNEL_INVALID	-
1708 */
1709npi_status_t
1710npi_txdma_desc_kick_reg_get(npi_handle_t handle, uint8_t channel,
1711		p_tx_ring_kick_t kick_p)
1712{
1713	int		status = NPI_SUCCESS;
1714
1715	ASSERT(TXDMA_CHANNEL_VALID(channel));
1716	if (!TXDMA_CHANNEL_VALID(channel)) {
1717		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1718		    " npi_txdma_desc_kick_reg_get"
1719		    " Invalid Input: channel <0x%x>",
1720		    channel));
1721		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1722	}
1723
1724	TXDMA_REG_READ64(handle, TX_RING_KICK_REG, channel, &kick_p->value);
1725
1726	return (status);
1727}
1728
1729/*
1730 * npi_txdma_ring_head_get():
1731 *	This function is called to get the transmit ring head index.
1732 *
1733 * Parameters:
1734 *	handle		- NPI handle (virtualization flag must be defined).
1735 *	channel		- logical TXDMA channel from 0 to 23.
1736 *			  (If virtualization flag is not set, then
1737 *			   logical channel is the same as the hardware
1738 *			   channel number).
1739 *	hdl_p		- pointer to the hardware defined transmit
1740 *			  ring header data (head index and wrap bit).
1741 *
1742 * Return:
1743 *	NPI_SUCCESS		- If get is complete successfully.
1744 *
1745 *	Error:
1746 *	NPI_FAILURE		-
1747 *		NPI_TXDMA_CHANNEL_INVALID	-
1748 */
1749npi_status_t
1750npi_txdma_ring_head_get(npi_handle_t handle, uint8_t channel,
1751		p_tx_ring_hdl_t hdl_p)
1752{
1753	int		status = NPI_SUCCESS;
1754
1755	ASSERT(TXDMA_CHANNEL_VALID(channel));
1756	if (!TXDMA_CHANNEL_VALID(channel)) {
1757		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1758		    " npi_txdma_ring_head_get"
1759		    " Invalid Input: channel <0x%x>",
1760		    channel));
1761		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1762	}
1763
1764	TXDMA_REG_READ64(handle, TX_RING_HDL_REG, channel, &hdl_p->value);
1765
1766	return (status);
1767}
1768
1769/*ARGSUSED*/
1770npi_status_t
1771npi_txdma_channel_mbox_get(npi_handle_t handle, uint8_t channel,
1772		p_txdma_mailbox_t mbox_p)
1773{
1774	int		status = NPI_SUCCESS;
1775
1776	return (status);
1777
1778}
1779
1780npi_status_t
1781npi_txdma_channel_pre_state_get(npi_handle_t handle, uint8_t channel,
1782		p_tx_dma_pre_st_t prep)
1783{
1784	int		status = NPI_SUCCESS;
1785
1786	ASSERT(TXDMA_CHANNEL_VALID(channel));
1787	if (!TXDMA_CHANNEL_VALID(channel)) {
1788		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1789		    " npi_txdma_channel_pre_state_get"
1790		    " Invalid Input: channel <0x%x>",
1791		    channel));
1792		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1793	}
1794
1795	TXDMA_REG_READ64(handle, TX_DMA_PRE_ST_REG, channel, &prep->value);
1796
1797	return (status);
1798}
1799
1800npi_status_t
1801npi_txdma_ring_error_get(npi_handle_t handle, uint8_t channel,
1802		p_txdma_ring_errlog_t ring_errlog_p)
1803{
1804	tx_rng_err_logh_t	logh;
1805	tx_rng_err_logl_t	logl;
1806	int			status = NPI_SUCCESS;
1807
1808	ASSERT(TXDMA_CHANNEL_VALID(channel));
1809	if (!TXDMA_CHANNEL_VALID(channel)) {
1810		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1811		    " npi_txdma_ring_error_get"
1812		    " Invalid Input: channel <0x%x>",
1813		    channel));
1814		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1815	}
1816
1817	logh.value = 0;
1818	TXDMA_REG_READ64(handle, TX_RNG_ERR_LOGH_REG, channel, &logh.value);
1819	TXDMA_REG_READ64(handle, TX_RNG_ERR_LOGL_REG, channel, &logl.value);
1820	ring_errlog_p->logh.bits.ldw.err = logh.bits.ldw.err;
1821	ring_errlog_p->logh.bits.ldw.merr = logh.bits.ldw.merr;
1822	ring_errlog_p->logh.bits.ldw.errcode = logh.bits.ldw.errcode;
1823	ring_errlog_p->logh.bits.ldw.err_addr = logh.bits.ldw.err_addr;
1824	ring_errlog_p->logl.bits.ldw.err_addr = logl.bits.ldw.err_addr;
1825
1826	return (status);
1827}
1828
1829npi_status_t
1830npi_txdma_inj_par_error_clear(npi_handle_t handle)
1831{
1832	NXGE_REG_WR64(handle, TDMC_INJ_PAR_ERR_REG, 0);
1833
1834	return (NPI_SUCCESS);
1835}
1836
1837npi_status_t
1838npi_txdma_inj_par_error_set(npi_handle_t handle, uint32_t err_bits)
1839{
1840	tdmc_inj_par_err_t	inj;
1841
1842	inj.value = 0;
1843	inj.bits.ldw.inject_parity_error = (err_bits & TDMC_INJ_PAR_ERR_MASK);
1844	NXGE_REG_WR64(handle, TDMC_INJ_PAR_ERR_REG, inj.value);
1845
1846	return (NPI_SUCCESS);
1847}
1848
1849npi_status_t
1850npi_txdma_inj_par_error_update(npi_handle_t handle, uint32_t err_bits)
1851{
1852	tdmc_inj_par_err_t	inj;
1853
1854	inj.value = 0;
1855	NXGE_REG_RD64(handle, TDMC_INJ_PAR_ERR_REG, &inj.value);
1856	inj.value |= (err_bits & TDMC_INJ_PAR_ERR_MASK);
1857	NXGE_REG_WR64(handle, TDMC_INJ_PAR_ERR_REG, inj.value);
1858
1859	return (NPI_SUCCESS);
1860}
1861
1862npi_status_t
1863npi_txdma_inj_par_error_get(npi_handle_t handle, uint32_t *err_bits)
1864{
1865	tdmc_inj_par_err_t	inj;
1866
1867	inj.value = 0;
1868	NXGE_REG_RD64(handle, TDMC_INJ_PAR_ERR_REG, &inj.value);
1869	*err_bits = (inj.value & TDMC_INJ_PAR_ERR_MASK);
1870
1871	return (NPI_SUCCESS);
1872}
1873
1874npi_status_t
1875npi_txdma_dbg_sel_set(npi_handle_t handle, uint8_t dbg_sel)
1876{
1877	tdmc_dbg_sel_t		dbg;
1878
1879	dbg.value = 0;
1880	dbg.bits.ldw.dbg_sel = (dbg_sel & TDMC_DBG_SEL_MASK);
1881
1882	NXGE_REG_WR64(handle, TDMC_DBG_SEL_REG, dbg.value);
1883
1884	return (NPI_SUCCESS);
1885}
1886
1887npi_status_t
1888npi_txdma_training_vector_set(npi_handle_t handle, uint32_t training_vector)
1889{
1890	tdmc_training_t		vec;
1891
1892	vec.value = 0;
1893	vec.bits.ldw.vec = training_vector;
1894
1895	NXGE_REG_WR64(handle, TDMC_TRAINING_REG, vec.value);
1896
1897	return (NPI_SUCCESS);
1898}
1899
1900/*
1901 * npi_txdma_dump_desc_one(npi_handle_t handle, p_tx_desc_t desc_p,
1902 *	int desc_index)
1903 *
1904 *	Dumps the contents of transmit descriptors.
1905 *
1906 * Parameters:
1907 *	handle		- NPI handle (register pointer is the
1908 *			  descriptor address in memory).
1909 *	desc_p		- pointer to place the descriptor contents
1910 *	desc_index	- descriptor index
1911 *
1912 */
1913/*ARGSUSED*/
1914void
1915npi_txdma_dump_desc_one(npi_handle_t handle, p_tx_desc_t desc_p, int desc_index)
1916{
1917
1918	tx_desc_t 		desc, *desp;
1919#ifdef NXGE_DEBUG
1920	uint64_t		sad;
1921	int			xfer_len;
1922#endif
1923
1924	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1925	    "\n==> npi_txdma_dump_desc_one: dump "
1926	    " desc_p $%p descriptor entry %d\n",
1927	    desc_p, desc_index));
1928	desc.value = 0;
1929	desp = ((desc_p != NULL) ? desc_p : (p_tx_desc_t)&desc);
1930	desp->value = NXGE_MEM_PIO_READ64(handle);
1931#ifdef NXGE_DEBUG
1932	sad = (desp->value & TX_PKT_DESC_SAD_MASK);
1933	xfer_len = ((desp->value & TX_PKT_DESC_TR_LEN_MASK) >>
1934	    TX_PKT_DESC_TR_LEN_SHIFT);
1935#endif
1936	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL, "\n\t: value 0x%llx\n"
1937	    "\t\tsad $%p\ttr_len %d len %d\tnptrs %d\tmark %d sop %d\n",
1938	    desp->value,
1939	    sad,
1940	    desp->bits.hdw.tr_len,
1941	    xfer_len,
1942	    desp->bits.hdw.num_ptr,
1943	    desp->bits.hdw.mark,
1944	    desp->bits.hdw.sop));
1945
1946	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1947	    "\n<== npi_txdma_dump_desc_one: Done \n"));
1948
1949}
1950
1951/*ARGSUSED*/
1952void
1953npi_txdma_dump_hdr(npi_handle_t handle, p_tx_pkt_header_t hdrp)
1954{
1955	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1956	    "\n==> npi_txdma_dump_hdr: dump\n"));
1957	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1958	    "\n\t: value 0x%llx\n"
1959	    "\t\tpkttype 0x%x\tip_ver %d\tllc %d\tvlan %d \tihl %d\n"
1960	    "\t\tl3start %d\tl4start %d\tl4stuff %d\n"
1961	    "\t\txferlen %d\tpad %d\n",
1962	    hdrp->value,
1963	    hdrp->bits.hdw.cksum_en_pkt_type,
1964	    hdrp->bits.hdw.ip_ver,
1965	    hdrp->bits.hdw.llc,
1966	    hdrp->bits.hdw.vlan,
1967	    hdrp->bits.hdw.ihl,
1968	    hdrp->bits.hdw.l3start,
1969	    hdrp->bits.hdw.l4start,
1970	    hdrp->bits.hdw.l4stuff,
1971	    hdrp->bits.ldw.tot_xfer_len,
1972	    hdrp->bits.ldw.pad));
1973
1974	NPI_DEBUG_MSG((handle.function, NPI_TDC_CTL,
1975	    "\n<== npi_txdma_dump_hdr: Done \n"));
1976}
1977
1978npi_status_t
1979npi_txdma_inj_int_error_set(npi_handle_t handle, uint8_t channel,
1980	p_tdmc_intr_dbg_t erp)
1981{
1982	int		status = NPI_SUCCESS;
1983
1984	ASSERT(TXDMA_CHANNEL_VALID(channel));
1985	if (!TXDMA_CHANNEL_VALID(channel)) {
1986		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
1987		    " npi_txdma_inj_int_error_set"
1988		    " Invalid Input: channel <0x%x>",
1989		    channel));
1990		return (NPI_FAILURE | NPI_TXDMA_CHANNEL_INVALID(channel));
1991	}
1992
1993	TXDMA_REG_WRITE64(handle, TDMC_INTR_DBG_REG, channel, erp->value);
1994
1995	return (status);
1996}
1997
1998/*
1999 * Static functions start here.
2000 */
2001static npi_status_t
2002npi_txdma_control_reset_wait(npi_handle_t handle, uint8_t channel)
2003{
2004
2005	tx_cs_t		txcs;
2006	int		loop = 0;
2007
2008	do {
2009		NXGE_DELAY(TXDMA_WAIT_MSEC);
2010		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &txcs.value);
2011		if (!txcs.bits.ldw.rst) {
2012			return (NPI_SUCCESS);
2013		}
2014		loop++;
2015	} while (loop < TXDMA_WAIT_LOOP);
2016
2017	if (loop == TXDMA_WAIT_LOOP) {
2018		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2019		    "npi_txdma_control_reset_wait: RST bit not "
2020		    "cleared to 0 txcs.bits 0x%llx", txcs.value));
2021		return (NPI_FAILURE | NPI_TXDMA_RESET_FAILED);
2022	}
2023	return (NPI_SUCCESS);
2024}
2025
2026static npi_status_t
2027npi_txdma_control_stop_wait(npi_handle_t handle, uint8_t channel)
2028{
2029	tx_cs_t		txcs;
2030	int		loop = 0;
2031
2032	do {
2033		NXGE_DELAY(TXDMA_WAIT_MSEC);
2034		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &txcs.value);
2035		if (txcs.bits.ldw.sng_state) {
2036			return (NPI_SUCCESS);
2037		}
2038		loop++;
2039	} while (loop < TXDMA_WAIT_LOOP);
2040
2041	if (loop == TXDMA_WAIT_LOOP) {
2042		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2043		    "npi_txdma_control_stop_wait: SNG_STATE not "
2044		    "set to 1 txcs.bits 0x%llx", txcs.value));
2045		return (NPI_FAILURE | NPI_TXDMA_STOP_FAILED);
2046	}
2047
2048	return (NPI_SUCCESS);
2049}
2050
2051static npi_status_t
2052npi_txdma_control_resume_wait(npi_handle_t handle, uint8_t channel)
2053{
2054	tx_cs_t		txcs;
2055	int		loop = 0;
2056
2057	do {
2058		NXGE_DELAY(TXDMA_WAIT_MSEC);
2059		TXDMA_REG_READ64(handle, TX_CS_REG, channel, &txcs.value);
2060		if (!txcs.bits.ldw.sng_state) {
2061			return (NPI_SUCCESS);
2062		}
2063		loop++;
2064	} while (loop < TXDMA_WAIT_LOOP);
2065
2066	if (loop == TXDMA_WAIT_LOOP) {
2067		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
2068		    "npi_txdma_control_resume_wait: sng_state not "
2069		    "set to 0 txcs.bits 0x%llx", txcs.value));
2070		return (NPI_FAILURE | NPI_TXDMA_RESUME_FAILED);
2071	}
2072
2073	return (NPI_SUCCESS);
2074}
2075