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