1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include <npi_zcp.h>
29
30static int zcp_mem_read(npi_handle_t, uint16_t, uint8_t,
31	uint16_t, zcp_ram_unit_t *);
32static int zcp_mem_write(npi_handle_t, uint16_t, uint8_t,
33	uint32_t, uint16_t, zcp_ram_unit_t *);
34
35npi_status_t
36npi_zcp_config(npi_handle_t handle, config_op_t op, zcp_config_t config)
37{
38	uint64_t val = 0;
39
40	switch (op) {
41	case ENABLE:
42	case DISABLE:
43		if ((config == 0) || (config & ~CFG_ZCP_ALL) != 0) {
44			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
45			    " npi_zcp_config"
46			    " Invalid Input: config <0x%x>",
47			    config));
48			return (NPI_FAILURE | NPI_ZCP_CONFIG_INVALID);
49		}
50
51		NXGE_REG_RD64(handle, ZCP_CONFIG_REG, &val);
52		if (op == ENABLE) {
53			if (config & CFG_ZCP)
54				val |= ZC_ENABLE;
55			if (config & CFG_ZCP_ECC_CHK)
56				val &= ~ECC_CHK_DIS;
57			if (config & CFG_ZCP_PAR_CHK)
58				val &= ~PAR_CHK_DIS;
59			if (config & CFG_ZCP_BUF_RESP)
60				val &= ~DIS_BUFF_RN;
61			if (config & CFG_ZCP_BUF_REQ)
62				val &= ~DIS_BUFF_RQ_IF;
63		} else {
64			if (config & CFG_ZCP)
65				val &= ~ZC_ENABLE;
66			if (config & CFG_ZCP_ECC_CHK)
67				val |= ECC_CHK_DIS;
68			if (config & CFG_ZCP_PAR_CHK)
69				val |= PAR_CHK_DIS;
70			if (config & CFG_ZCP_BUF_RESP)
71				val |= DIS_BUFF_RN;
72			if (config & CFG_ZCP_BUF_REQ)
73				val |= DIS_BUFF_RQ_IF;
74		}
75		NXGE_REG_WR64(handle, ZCP_CONFIG_REG, val);
76
77		break;
78	case INIT:
79		NXGE_REG_RD64(handle, ZCP_CONFIG_REG, &val);
80		val &= ((ZCP_DEBUG_SEL_MASK) | (RDMA_TH_MASK));
81		if (config & CFG_ZCP)
82			val |= ZC_ENABLE;
83		else
84			val &= ~ZC_ENABLE;
85		if (config & CFG_ZCP_ECC_CHK)
86			val &= ~ECC_CHK_DIS;
87		else
88			val |= ECC_CHK_DIS;
89		if (config & CFG_ZCP_PAR_CHK)
90			val &= ~PAR_CHK_DIS;
91		else
92			val |= PAR_CHK_DIS;
93		if (config & CFG_ZCP_BUF_RESP)
94			val &= ~DIS_BUFF_RN;
95		else
96			val |= DIS_BUFF_RN;
97		if (config & CFG_ZCP_BUF_REQ)
98			val &= DIS_BUFF_RQ_IF;
99		else
100			val |= DIS_BUFF_RQ_IF;
101		NXGE_REG_WR64(handle, ZCP_CONFIG_REG, val);
102
103		break;
104	default:
105		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
106		    " npi_zcp_config"
107		    " Invalid Input: config <0x%x>",
108		    config));
109		return (NPI_FAILURE | NPI_ZCP_OPCODE_INVALID);
110	}
111
112	return (NPI_SUCCESS);
113}
114
115npi_status_t
116npi_zcp_iconfig(npi_handle_t handle, config_op_t op, zcp_iconfig_t iconfig)
117{
118	uint64_t val = 0;
119
120	switch (op) {
121	case ENABLE:
122	case DISABLE:
123		if ((iconfig == 0) || (iconfig & ~ICFG_ZCP_ALL) != 0) {
124			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
125			    " npi_zcp_iconfig"
126			    " Invalid Input: iconfig <0x%x>",
127			    iconfig));
128			return (NPI_FAILURE | NPI_ZCP_CONFIG_INVALID);
129		}
130
131		NXGE_REG_RD64(handle, ZCP_INT_MASK_REG, &val);
132		if (op == ENABLE)
133			val |= iconfig;
134		else
135			val &= ~iconfig;
136		NXGE_REG_WR64(handle, ZCP_INT_MASK_REG, val);
137
138		break;
139
140	case INIT:
141		if ((iconfig & ~ICFG_ZCP_ALL) != 0) {
142			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
143			    " npi_zcp_iconfig"
144			    " Invalid Input: iconfig <0x%x>",
145			    iconfig));
146			return (NPI_FAILURE | NPI_ZCP_CONFIG_INVALID);
147		}
148		val = (uint64_t)iconfig;
149		NXGE_REG_WR64(handle, ZCP_INT_MASK_REG, val);
150
151		break;
152	default:
153		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
154		    " npi_zcp_iconfig"
155		    " Invalid Input: iconfig <0x%x>",
156		    iconfig));
157		return (NPI_FAILURE | NPI_ZCP_OPCODE_INVALID);
158	}
159
160	return (NPI_SUCCESS);
161}
162
163npi_status_t
164npi_zcp_get_istatus(npi_handle_t handle, zcp_iconfig_t *istatus)
165{
166	uint64_t val;
167
168	NXGE_REG_RD64(handle, ZCP_INT_STAT_REG, &val);
169	*istatus = (uint32_t)val;
170
171	return (NPI_SUCCESS);
172}
173
174npi_status_t
175npi_zcp_clear_istatus(npi_handle_t handle)
176{
177	uint64_t val;
178
179	val = (uint64_t)0xffff;
180	NXGE_REG_WR64(handle, ZCP_INT_STAT_REG, val);
181	return (NPI_SUCCESS);
182}
183
184
185npi_status_t
186npi_zcp_set_dma_thresh(npi_handle_t handle, uint16_t dma_thres)
187{
188	uint64_t val = 0;
189
190	if ((dma_thres & ~RDMA_TH_BITS) != 0) {
191		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
192		    " npi_zcp_set_dma_thresh"
193		    " Invalid Input: dma_thres <0x%x>",
194		    dma_thres));
195		return (NPI_FAILURE | NPI_ZCP_DMA_THRES_INVALID);
196	}
197
198	NXGE_REG_RD64(handle, ZCP_CONFIG_REG, &val);
199
200	val &= ~RDMA_TH_MASK;
201	val |= (dma_thres << RDMA_TH_SHIFT);
202
203	NXGE_REG_WR64(handle, ZCP_CONFIG_REG, val);
204
205	return (NPI_SUCCESS);
206}
207
208npi_status_t
209npi_zcp_set_bam_region(npi_handle_t handle, zcp_buf_region_t region,
210			zcp_bam_region_reg_t *region_attr)
211{
212
213	ASSERT(IS_VALID_BAM_REGION(region));
214	if (!IS_VALID_BAM_REGION(region)) {
215		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
216		    " npi_zcp_set_bam_region"
217		    " Invalid Input: region <0x%x>",
218		    region));
219		return (NPI_FAILURE | ZCP_BAM_REGION_INVALID);
220	}
221
222	switch (region) {
223	case BAM_4BUF:
224		NXGE_REG_WR64(handle, ZCP_BAM4_RE_CTL_REG, region_attr->value);
225		break;
226	case BAM_8BUF:
227		NXGE_REG_WR64(handle, ZCP_BAM8_RE_CTL_REG, region_attr->value);
228		break;
229	case BAM_16BUF:
230		NXGE_REG_WR64(handle, ZCP_BAM16_RE_CTL_REG, region_attr->value);
231		break;
232	case BAM_32BUF:
233		NXGE_REG_WR64(handle, ZCP_BAM32_RE_CTL_REG, region_attr->value);
234		break;
235	}
236
237	return (NPI_SUCCESS);
238}
239
240npi_status_t
241npi_zcp_set_dst_region(npi_handle_t handle, zcp_buf_region_t region,
242				uint16_t row_idx)
243{
244	uint64_t val = 0;
245
246	ASSERT(IS_VALID_BAM_REGION(region));
247	if (!IS_VALID_BAM_REGION(region)) {
248		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
249		    " npi_zcp_set_dst_region"
250		    " Invalid Input: region <0x%x>",
251		    region));
252		return (NPI_FAILURE | NPI_ZCP_BAM_REGION_INVALID);
253	}
254
255	if ((row_idx & ~0x3FF) != 0) {
256		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
257		    " npi_zcp_set_dst_region"
258		    " Invalid Input: row_idx", row_idx));
259		return (NPI_FAILURE | NPI_ZCP_ROW_INDEX_INVALID);
260	}
261
262	val = (uint64_t)row_idx;
263
264	switch (region) {
265	case BAM_4BUF:
266		NXGE_REG_WR64(handle, ZCP_DST4_RE_CTL_REG, val);
267		break;
268	case BAM_8BUF:
269		NXGE_REG_WR64(handle, ZCP_DST8_RE_CTL_REG, val);
270		break;
271	case BAM_16BUF:
272		NXGE_REG_WR64(handle, ZCP_DST16_RE_CTL_REG, val);
273		break;
274	case BAM_32BUF:
275		NXGE_REG_WR64(handle, ZCP_DST32_RE_CTL_REG, val);
276		break;
277	}
278
279	return (NPI_SUCCESS);
280}
281
282npi_status_t
283npi_zcp_tt_static_entry(npi_handle_t handle, io_op_t op, uint16_t flow_id,
284			tte_sflow_attr_mask_t mask, tte_sflow_attr_t *sflow)
285{
286	uint32_t		byte_en = 0;
287	tte_sflow_attr_t	val;
288
289	if ((op != OP_SET) && (op != OP_GET)) {
290		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
291		    " npi_zcp_tt_static_entry"
292		    " Invalid Input: op <0x%x>",
293		    op));
294		return (NPI_FAILURE | NPI_ZCP_OPCODE_INVALID);
295	}
296
297	if ((mask & TTE_SFLOW_ATTR_ALL) == 0) {
298		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
299		    " npi_zcp_tt_static_entry"
300		    " Invalid Input: mask <0x%x>",
301		    mask));
302		return (NPI_FAILURE | NPI_ZCP_SFLOW_ATTR_INVALID);
303	}
304
305	if ((flow_id & ~0x0FFF) != 0) {
306		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
307		    " npi_zcp_tt_static_entry"
308		    " Invalid Input: flow_id<0x%x>",
309		    flow_id));
310		return (NPI_FAILURE | NPI_ZCP_FLOW_ID_INVALID);
311	}
312
313	if (zcp_mem_read(handle, flow_id, ZCP_RAM_SEL_TT_STATIC, NULL,
314	    (zcp_ram_unit_t *)&val) != 0) {
315		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
316		    " npi_zcp_tt_static_entry"
317		    " HW Error: ZCP_RAM_ACC <0x%x>",
318		    NULL));
319		return (NPI_FAILURE | NPI_ZCP_MEM_READ_FAILED);
320	}
321
322	if (op == OP_SET) {
323		if (mask & TTE_RDC_TBL_OFF) {
324			val.qw0.bits.ldw.rdc_tbl_offset =
325			    sflow->qw0.bits.ldw.rdc_tbl_offset;
326			byte_en |= TTE_RDC_TBL_SFLOW_BITS_EN;
327		}
328		if (mask & TTE_BUF_SIZE) {
329			val.qw0.bits.ldw.buf_size =
330			    sflow->qw0.bits.ldw.buf_size;
331			byte_en |= TTE_BUF_SIZE_BITS_EN;
332		}
333		if (mask & TTE_NUM_BUF) {
334			val.qw0.bits.ldw.num_buf = sflow->qw0.bits.ldw.num_buf;
335			byte_en |= TTE_NUM_BUF_BITS_EN;
336		}
337		if (mask & TTE_ULP_END) {
338			val.qw0.bits.ldw.ulp_end = sflow->qw0.bits.ldw.ulp_end;
339			byte_en |=  TTE_ULP_END_BITS_EN;
340		}
341		if (mask & TTE_ULP_END) {
342			val.qw1.bits.ldw.ulp_end = sflow->qw1.bits.ldw.ulp_end;
343			byte_en |= TTE_ULP_END_BITS_EN;
344		}
345		if (mask & TTE_ULP_END_EN) {
346			val.qw1.bits.ldw.ulp_end_en =
347			    sflow->qw1.bits.ldw.ulp_end_en;
348			byte_en |= TTE_ULP_END_EN_BITS_EN;
349		}
350		if (mask & TTE_UNMAP_ALL_EN) {
351			val.qw1.bits.ldw.unmap_all_en =
352			    sflow->qw1.bits.ldw.unmap_all_en;
353			byte_en |= TTE_UNMAP_ALL_EN;
354		}
355		if (mask & TTE_TMODE) {
356			val.qw1.bits.ldw.tmode = sflow->qw1.bits.ldw.tmode;
357			byte_en |= TTE_TMODE_BITS_EN;
358		}
359		if (mask & TTE_SKIP) {
360			val.qw1.bits.ldw.skip = sflow->qw1.bits.ldw.skip;
361			byte_en |= TTE_SKIP_BITS_EN;
362		}
363		if (mask & TTE_HBM_RING_BASE_ADDR) {
364			val.qw1.bits.ldw.ring_base =
365			    sflow->qw1.bits.ldw.ring_base;
366			byte_en |= TTE_RING_BASE_ADDR_BITS_EN;
367		}
368		if (mask & TTE_HBM_RING_BASE_ADDR) {
369			val.qw2.bits.ldw.ring_base =
370			    sflow->qw2.bits.ldw.ring_base;
371			byte_en |= TTE_RING_BASE_ADDR_BITS_EN;
372		}
373		if (mask & TTE_HBM_RING_SIZE) {
374			val.qw2.bits.ldw.ring_size =
375			    sflow->qw2.bits.ldw.ring_size;
376			byte_en |= TTE_RING_SIZE_BITS_EN;
377		}
378		if (mask & TTE_HBM_BUSY) {
379			val.qw2.bits.ldw.busy = sflow->qw2.bits.ldw.busy;
380			byte_en |= TTE_BUSY_BITS_EN;
381		}
382		if (mask & TTE_HBM_TOQ) {
383			val.qw3.bits.ldw.toq = sflow->qw3.bits.ldw.toq;
384			byte_en |= TTE_TOQ_BITS_EN;
385		}
386
387		if (zcp_mem_write(handle, flow_id, ZCP_RAM_SEL_TT_STATIC,
388		    byte_en, NULL,
389		    (zcp_ram_unit_t *)&val) != 0) {
390			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
391			    " npi_zcp_tt_static_entry"
392			    " HW Error: ZCP_RAM_ACC <0x%x>",
393			    NULL));
394			return (NPI_FAILURE | NPI_ZCP_MEM_WRITE_FAILED);
395		}
396	} else {
397		sflow->qw0.value = val.qw0.value;
398		sflow->qw1.value = val.qw1.value;
399		sflow->qw2.value = val.qw2.value;
400		sflow->qw3.value = val.qw3.value;
401		sflow->qw4.value = val.qw4.value;
402	}
403
404	return (NPI_SUCCESS);
405}
406
407npi_status_t
408npi_zcp_tt_dynamic_entry(npi_handle_t handle, io_op_t op, uint16_t flow_id,
409			tte_dflow_attr_mask_t mask, tte_dflow_attr_t *dflow)
410{
411	uint32_t		byte_en = 0;
412	tte_dflow_attr_t	val;
413
414	if ((op != OP_SET) && (op != OP_GET)) {
415		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
416		    " npi_zcp_tt_dynamic_entry"
417		    " Invalid Input: op <0x%x>", op));
418		return (NPI_FAILURE | NPI_ZCP_OPCODE_INVALID);
419	}
420
421	if ((mask & TTE_DFLOW_ATTR_ALL) == 0) {
422		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
423		    " npi_zcp_tt_dynamic_entry"
424		    " Invalid Input: mask <0x%x>",
425		    mask));
426		return (NPI_FAILURE | NPI_ZCP_DFLOW_ATTR_INVALID);
427	}
428
429	if ((flow_id & ~0x0FFF) != 0) {
430		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
431		    " npi_zcp_tt_dynamic_entry"
432		    " Invalid Input: flow_id <0x%x>",
433		    flow_id));
434		return (NPI_FAILURE | NPI_ZCP_FLOW_ID_INVALID);
435	}
436
437	if (zcp_mem_read(handle, flow_id, ZCP_RAM_SEL_TT_DYNAMIC, NULL,
438	    (zcp_ram_unit_t *)&val) != 0) {
439		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
440		    " npi_zcp_tt_dynamic_entry"
441		    " HW Error: ZCP_RAM_ACC <0x%x>",
442		    NULL));
443		return (NPI_FAILURE | NPI_ZCP_MEM_READ_FAILED);
444	}
445
446	if (op == OP_SET) {
447
448		/* Get data read */
449		if (mask & TTE_MAPPED_IN) {
450			val.qw0.bits.ldw.mapped_in =
451			    dflow->qw0.bits.ldw.mapped_in;
452			byte_en |= TTE_MAPPED_IN_BITS_EN;
453		}
454		if (mask & TTE_ANCHOR_SEQ) {
455			val.qw1.bits.ldw.anchor_seq =
456			    dflow->qw1.bits.ldw.anchor_seq;
457			byte_en |= TTE_ANCHOR_SEQ_BITS_EN;
458		}
459		if (mask & TTE_ANCHOR_OFFSET) {
460			val.qw2.bits.ldw.anchor_offset =
461			    dflow->qw2.bits.ldw.anchor_offset;
462			byte_en |= TTE_ANCHOR_OFFSET_BITS_EN;
463		}
464		if (mask & TTE_ANCHOR_BUFFER) {
465			val.qw2.bits.ldw.anchor_buf =
466			    dflow->qw2.bits.ldw.anchor_buf;
467			byte_en |= TTE_ANCHOR_BUFFER_BITS_EN;
468		}
469		if (mask & TTE_ANCHOR_BUF_FLAG) {
470			val.qw2.bits.ldw.anchor_buf_flag =
471			    dflow->qw2.bits.ldw.anchor_buf_flag;
472			byte_en |= TTE_ANCHOR_BUF_FLAG_BITS_EN;
473		}
474		if (mask & TTE_UNMAP_ON_LEFT) {
475			val.qw2.bits.ldw.unmap_on_left =
476			    dflow->qw2.bits.ldw.unmap_on_left;
477			byte_en |= TTE_UNMAP_ON_LEFT_BITS_EN;
478		}
479		if (mask & TTE_ULP_END_REACHED) {
480			val.qw2.bits.ldw.ulp_end_reached =
481			    dflow->qw2.bits.ldw.ulp_end_reached;
482			byte_en |= TTE_ULP_END_REACHED_BITS_EN;
483		}
484		if (mask & TTE_ERR_STAT) {
485			val.qw3.bits.ldw.err_stat =
486			    dflow->qw3.bits.ldw.err_stat;
487			byte_en |= TTE_ERR_STAT_BITS_EN;
488		}
489		if (mask & TTE_HBM_WR_PTR) {
490			val.qw3.bits.ldw.wr_ptr = dflow->qw3.bits.ldw.wr_ptr;
491			byte_en |= TTE_WR_PTR_BITS_EN;
492		}
493		if (mask & TTE_HBM_HOQ) {
494			val.qw3.bits.ldw.hoq = dflow->qw3.bits.ldw.hoq;
495			byte_en |= TTE_HOQ_BITS_EN;
496		}
497		if (mask & TTE_HBM_PREFETCH_ON) {
498			val.qw3.bits.ldw.prefetch_on =
499			    dflow->qw3.bits.ldw.prefetch_on;
500			byte_en |= TTE_PREFETCH_ON_BITS_EN;
501		}
502
503		if (zcp_mem_write(handle, flow_id, ZCP_RAM_SEL_TT_DYNAMIC,
504		    byte_en, NULL,
505		    (zcp_ram_unit_t *)&val) != 0) {
506			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
507			    " npi_zcp_tt_dynamic_entry"
508			    " HW Error: ZCP_RAM_ACC <0x%x>",
509			    NULL));
510			return (NPI_FAILURE | NPI_ZCP_MEM_WRITE_FAILED);
511		}
512	} else {
513		dflow->qw0.value = val.qw0.value;
514		dflow->qw1.value = val.qw1.value;
515		dflow->qw2.value = val.qw2.value;
516		dflow->qw3.value = val.qw3.value;
517		dflow->qw4.value = val.qw4.value;
518	}
519
520	return (NPI_SUCCESS);
521}
522
523npi_status_t
524npi_zcp_tt_bam_entry(npi_handle_t handle, io_op_t op, uint16_t flow_id,
525			uint8_t bankn, uint8_t word_en, zcp_ram_unit_t *data)
526{
527	zcp_ram_unit_t val;
528
529	if ((op != OP_SET) && (op != OP_GET)) {
530		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
531		    " npi_zcp_tt_bam_entry"
532		    " Invalid Input: op <0x%x>", op));
533		return (NPI_FAILURE | NPI_ZCP_OPCODE_INVALID);
534	}
535
536	if ((flow_id & ~0x0FFF) != 0) {
537		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
538		    " npi_zcp_tt_dynamic_entry"
539		    " Invalid Input: flow_id <0x%x>",
540		    flow_id));
541		return (NPI_FAILURE | NPI_ZCP_FLOW_ID_INVALID);
542	}
543
544	if (bankn >= MAX_BAM_BANKS) {
545		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
546		    " npi_zcp_tt_bam_entry"
547		    " Invalid Input: bankn <0x%x>",
548		    bankn));
549		return (NPI_FAILURE | NPI_ZCP_BAM_BANK_INVALID);
550	}
551
552	if ((word_en & ~0xF) != 0) {
553		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
554		    " npi_zcp_tt_bam_entry"
555		    " Invalid Input: word_en <0x%x>",
556		    word_en));
557		return (NPI_FAILURE | NPI_ZCP_BAM_WORD_EN_INVALID);
558	}
559
560	if (zcp_mem_read(handle, flow_id, ZCP_RAM_SEL_BAM0 + bankn, NULL,
561	    (zcp_ram_unit_t *)&val) != 0) {
562		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
563		    " npi_zcp_tt_bam_entry"
564		    " HW Error: ZCP_RAM_ACC <0x%x>",
565		    NULL));
566		return (NPI_FAILURE | NPI_ZCP_MEM_READ_FAILED);
567	}
568
569	if (op == OP_SET) {
570		if (zcp_mem_write(handle, flow_id, ZCP_RAM_SEL_BAM0 + bankn,
571		    word_en, NULL,
572		    (zcp_ram_unit_t *)&val) != 0) {
573			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
574			    " npi_zcp_tt_bam_entry"
575			    " HW Error: ZCP_RAM_ACC <0x%x>",
576			    NULL));
577			return (NPI_FAILURE | NPI_ZCP_MEM_WRITE_FAILED);
578		}
579	} else {
580		data->w0 = val.w0;
581		data->w1 = val.w1;
582		data->w2 = val.w2;
583		data->w3 = val.w3;
584	}
585
586	return (NPI_SUCCESS);
587}
588
589npi_status_t
590npi_zcp_tt_cfifo_entry(npi_handle_t handle, io_op_t op, uint8_t portn,
591			uint16_t entryn, zcp_ram_unit_t *data)
592{
593	if ((op != OP_SET) && (op != OP_GET)) {
594		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
595		    " npi_zcp_tt_cfifo_entry"
596		    " Invalid Input: op <0x%x>", op));
597		return (NPI_FAILURE | NPI_ZCP_OPCODE_INVALID);
598	}
599
600	if (portn > 3) {
601		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
602		    " npi_zcp_tt_cfifo_entry"
603		    " Invalid Input: portn <%d>", portn));
604		return (NPI_FAILURE | NPI_ZCP_PORT_INVALID(portn));
605	}
606
607	if (op == OP_SET) {
608		if (zcp_mem_write(handle, NULL, ZCP_RAM_SEL_CFIFO0 + portn,
609		    0x1ffff, entryn, data) != 0) {
610			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
611			    " npi_zcp_tt_cfifo_entry"
612			    " HW Error: ZCP_RAM_ACC <0x%x>",
613			    NULL));
614			return (NPI_FAILURE | NPI_ZCP_MEM_WRITE_FAILED);
615		}
616	} else {
617		if (zcp_mem_read(handle, NULL, ZCP_RAM_SEL_CFIFO0 + portn,
618		    entryn, data) != 0) {
619			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
620			    " npi_zcp_tt_cfifo_entry"
621			    " HW Error: ZCP_RAM_ACC  <0x%x>",
622			    NULL));
623			return (NPI_FAILURE | NPI_ZCP_MEM_READ_FAILED);
624		}
625	}
626
627	return (NPI_SUCCESS);
628}
629
630npi_status_t
631npi_zcp_rest_cfifo_port(npi_handle_t handle, uint8_t port)
632{
633	uint64_t offset = ZCP_RESET_CFIFO_REG;
634	zcp_reset_cfifo_t cfifo_reg;
635	NXGE_REG_RD64(handle, offset, &cfifo_reg.value);
636	cfifo_reg.value &= ZCP_RESET_CFIFO_MASK;
637
638	switch (port) {
639		case 0:
640			cfifo_reg.bits.ldw.reset_cfifo0 = 1;
641			NXGE_REG_WR64(handle, offset, cfifo_reg.value);
642			cfifo_reg.bits.ldw.reset_cfifo0 = 0;
643
644			break;
645		case 1:
646			cfifo_reg.bits.ldw.reset_cfifo1 = 1;
647			NXGE_REG_WR64(handle, offset, cfifo_reg.value);
648			cfifo_reg.bits.ldw.reset_cfifo1 = 0;
649			break;
650		case 2:
651			cfifo_reg.bits.ldw.reset_cfifo2 = 1;
652			NXGE_REG_WR64(handle, offset, cfifo_reg.value);
653			cfifo_reg.bits.ldw.reset_cfifo2 = 0;
654			break;
655		case 3:
656			cfifo_reg.bits.ldw.reset_cfifo3 = 1;
657			NXGE_REG_WR64(handle, offset, cfifo_reg.value);
658			cfifo_reg.bits.ldw.reset_cfifo3 = 0;
659			break;
660		default:
661			break;
662	}
663
664	NXGE_DELAY(ZCP_CFIFIO_RESET_WAIT);
665	NXGE_REG_WR64(handle, offset, cfifo_reg.value);
666
667	return (NPI_SUCCESS);
668}
669
670npi_status_t
671npi_zcp_rest_cfifo_all(npi_handle_t handle)
672{
673	uint64_t offset = ZCP_RESET_CFIFO_REG;
674	zcp_reset_cfifo_t cfifo_reg;
675
676	cfifo_reg.value = ZCP_RESET_CFIFO_MASK;
677	NXGE_REG_WR64(handle, offset, cfifo_reg.value);
678	cfifo_reg.value = 0;
679	NXGE_DELAY(ZCP_CFIFIO_RESET_WAIT);
680	NXGE_REG_WR64(handle, offset, cfifo_reg.value);
681	return (NPI_SUCCESS);
682}
683
684static int
685zcp_mem_read(npi_handle_t handle, uint16_t flow_id, uint8_t ram_sel,
686		uint16_t cfifo_entryn, zcp_ram_unit_t *val)
687{
688	zcp_ram_access_t ram_ctl;
689
690	ram_ctl.value = 0;
691	ram_ctl.bits.ldw.ram_sel = ram_sel;
692	ram_ctl.bits.ldw.zcfid = flow_id;
693	ram_ctl.bits.ldw.rdwr = ZCP_RAM_RD;
694	ram_ctl.bits.ldw.cfifo = cfifo_entryn;
695
696	/* Wait for RAM ready to be read */
697	ZCP_WAIT_RAM_READY(handle, ram_ctl.value);
698	if (ram_ctl.bits.ldw.busy != 0) {
699		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
700		    " npi_zcp_tt_static_entry"
701		    " HW Error: ZCP_RAM_ACC <0x%x>",
702		    ram_ctl.value));
703		return (-1);
704	}
705
706	/* Read from RAM */
707	NXGE_REG_WR64(handle, ZCP_RAM_ACC_REG, ram_ctl.value);
708
709	/* Wait for RAM read done */
710	ZCP_WAIT_RAM_READY(handle, ram_ctl.value);
711	if (ram_ctl.bits.ldw.busy != 0)
712		return (-1);
713
714	/* Get data */
715	NXGE_REG_RD64(handle, ZCP_RAM_DATA0_REG, &val->w0);
716	NXGE_REG_RD64(handle, ZCP_RAM_DATA1_REG, &val->w1);
717	NXGE_REG_RD64(handle, ZCP_RAM_DATA2_REG, &val->w2);
718	NXGE_REG_RD64(handle, ZCP_RAM_DATA3_REG, &val->w3);
719	NXGE_REG_RD64(handle, ZCP_RAM_DATA4_REG, &val->w4);
720
721	return (0);
722}
723
724static int
725zcp_mem_write(npi_handle_t handle, uint16_t flow_id, uint8_t ram_sel,
726		uint32_t byte_en, uint16_t cfifo_entryn, zcp_ram_unit_t *val)
727{
728	zcp_ram_access_t	ram_ctl;
729	zcp_ram_benable_t	ram_en;
730
731	ram_ctl.value = 0;
732	ram_ctl.bits.ldw.ram_sel = ram_sel;
733	ram_ctl.bits.ldw.zcfid = flow_id;
734	ram_ctl.bits.ldw.rdwr = ZCP_RAM_WR;
735	ram_en.bits.ldw.be = byte_en;
736	ram_ctl.bits.ldw.cfifo = cfifo_entryn;
737
738	/* Setup data */
739	NXGE_REG_WR64(handle, ZCP_RAM_DATA0_REG, val->w0);
740	NXGE_REG_WR64(handle, ZCP_RAM_DATA1_REG, val->w1);
741	NXGE_REG_WR64(handle, ZCP_RAM_DATA2_REG, val->w2);
742	NXGE_REG_WR64(handle, ZCP_RAM_DATA3_REG, val->w3);
743	NXGE_REG_WR64(handle, ZCP_RAM_DATA4_REG, val->w4);
744
745	/* Set byte mask */
746	NXGE_REG_WR64(handle, ZCP_RAM_BE_REG, ram_en.value);
747
748	/* Write to RAM */
749	NXGE_REG_WR64(handle, ZCP_RAM_ACC_REG, ram_ctl.value);
750
751	/* Wait for RAM write complete */
752	ZCP_WAIT_RAM_READY(handle, ram_ctl.value);
753	if (ram_ctl.bits.ldw.busy != 0)
754		return (-1);
755
756	return (0);
757}
758