xref: /illumos-gate/usr/src/uts/common/io/nxge/npi/npi_zcp.c (revision d1419d5a02eaedd520f925cd465fd62f3950ae43)
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 
30 static int zcp_mem_read(npi_handle_t, uint16_t, uint8_t,
31 	uint16_t, zcp_ram_unit_t *);
32 static int zcp_mem_write(npi_handle_t, uint16_t, uint8_t,
33 	uint32_t, uint16_t, zcp_ram_unit_t *);
34 
35 npi_status_t
36 npi_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 
115 npi_status_t
116 npi_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 
163 npi_status_t
164 npi_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 
174 npi_status_t
175 npi_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 
185 npi_status_t
186 npi_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 
208 npi_status_t
209 npi_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 
240 npi_status_t
241 npi_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 
282 npi_status_t
283 npi_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 
407 npi_status_t
408 npi_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 
523 npi_status_t
524 npi_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 
589 npi_status_t
590 npi_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 
630 npi_status_t
631 npi_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 
670 npi_status_t
671 npi_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 
684 static int
685 zcp_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 
724 static int
725 zcp_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