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