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