xref: /illumos-gate/usr/src/uts/common/io/nxge/npi/npi_txdma.c (revision 44bac77bf8165ebe38afb85dda247b928d88edf8)
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 
35 static npi_status_t npi_txdma_control_reset_wait(npi_handle_t handle,
36 	uint8_t channel);
37 static npi_status_t npi_txdma_control_stop_wait(npi_handle_t handle,
38 	uint8_t channel);
39 static npi_status_t npi_txdma_control_resume_wait(npi_handle_t handle,
40 	uint8_t channel);
41 
42 uint64_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 
57 const 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 
72 uint64_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 
83 const 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 
94 uint64_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 
103 const 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  */
128 npi_status_t
129 npi_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  */
179 npi_status_t
180 npi_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 
207 npi_status_t
208 npi_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  */
257 npi_status_t
258 npi_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  */
296 npi_status_t
297 npi_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  */
389 npi_status_t
390 npi_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  */
459 npi_status_t
460 npi_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  */
507 npi_status_t
508 npi_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,
596 				channel, (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  */
667 npi_status_t
668 npi_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  */
738 npi_status_t
739 npi_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  */
765 npi_status_t
766 npi_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 
789 npi_status_t
790 npi_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  */
813 npi_status_t
814 npi_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  */
837 npi_status_t
838 npi_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  */
860 npi_status_t
861 npi_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  */
884 npi_status_t
885 npi_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  */
918 npi_status_t
919 npi_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  */
1035 npi_status_t
1036 npi_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  */
1100 npi_status_t
1101 npi_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  */
1166 npi_status_t
1167 npi_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  */
1231 npi_status_t
1232 npi_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  */
1268 npi_status_t
1269 npi_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  */
1313 npi_status_t
1314 npi_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  */
1359 npi_status_t
1360 npi_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  */
1417 npi_status_t
1418 npi_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  */
1490 npi_status_t
1491 npi_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  */
1552 npi_status_t
1553 npi_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 }
1568 npi_status_t
1569 npi_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 
1587 npi_status_t
1588 npi_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 
1605 npi_status_t
1606 npi_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 
1623 npi_status_t
1624 npi_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  */
1656 npi_status_t
1657 npi_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  */
1709 npi_status_t
1710 npi_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  */
1749 npi_status_t
1750 npi_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*/
1770 npi_status_t
1771 npi_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 
1780 npi_status_t
1781 npi_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 
1800 npi_status_t
1801 npi_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 
1829 npi_status_t
1830 npi_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 
1837 npi_status_t
1838 npi_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 
1849 npi_status_t
1850 npi_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 
1862 npi_status_t
1863 npi_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 
1874 npi_status_t
1875 npi_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 
1887 npi_status_t
1888 npi_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*/
1914 void
1915 npi_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*/
1952 void
1953 npi_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 
1978 npi_status_t
1979 npi_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  */
2001 static npi_status_t
2002 npi_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 
2026 static npi_status_t
2027 npi_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 
2051 static npi_status_t
2052 npi_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