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