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