16349Sqs148142 /* 26349Sqs148142 * CDDL HEADER START 36349Sqs148142 * 46349Sqs148142 * The contents of this file are subject to the terms of the 56349Sqs148142 * Common Development and Distribution License (the "License"). 66349Sqs148142 * You may not use this file except in compliance with the License. 76349Sqs148142 * 86349Sqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96349Sqs148142 * or http://www.opensolaris.org/os/licensing. 106349Sqs148142 * See the License for the specific language governing permissions 116349Sqs148142 * and limitations under the License. 126349Sqs148142 * 136349Sqs148142 * When distributing Covered Code, include this CDDL HEADER in each 146349Sqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156349Sqs148142 * If applicable, add the following below this CDDL HEADER, with the 166349Sqs148142 * fields enclosed by brackets "[]" replaced with your own identifying 176349Sqs148142 * information: Portions Copyright [yyyy] [name of copyright owner] 186349Sqs148142 * 196349Sqs148142 * CDDL HEADER END 206349Sqs148142 */ 216349Sqs148142 /* 226349Sqs148142 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 236349Sqs148142 * Use is subject to license terms. 246349Sqs148142 */ 256349Sqs148142 266349Sqs148142 #include <hpi_rxdma.h> 276349Sqs148142 #include <hxge_common.h> 286864Sqs148142 #include <hxge_impl.h> 296349Sqs148142 306349Sqs148142 #define RXDMA_RESET_TRY_COUNT 5 316349Sqs148142 #define RXDMA_RESET_DELAY 5 326349Sqs148142 336349Sqs148142 #define RXDMA_OP_DISABLE 0 346349Sqs148142 #define RXDMA_OP_ENABLE 1 356349Sqs148142 #define RXDMA_OP_RESET 2 366349Sqs148142 376349Sqs148142 #define RCR_TIMEOUT_ENABLE 1 386349Sqs148142 #define RCR_TIMEOUT_DISABLE 2 396349Sqs148142 #define RCR_THRESHOLD 4 406349Sqs148142 416349Sqs148142 hpi_status_t 426349Sqs148142 hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle, uint8_t rdc, 436349Sqs148142 uint64_t page_handle) 446349Sqs148142 { 456349Sqs148142 rdc_page_handle_t page_hdl; 466349Sqs148142 476349Sqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 486349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 496349Sqs148142 "rxdma_cfg_logical_page_handle" 506349Sqs148142 " Illegal RDC number %d \n", rdc)); 516349Sqs148142 return (HPI_RXDMA_RDC_INVALID); 526349Sqs148142 } 536349Sqs148142 546349Sqs148142 page_hdl.value = 0; 556349Sqs148142 page_hdl.bits.handle = (uint32_t)page_handle; 566349Sqs148142 576349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_hdl.value); 586349Sqs148142 596349Sqs148142 return (HPI_SUCCESS); 606349Sqs148142 } 616349Sqs148142 62*7959SMichael.Speer@Sun.COM hpi_status_t 63*7959SMichael.Speer@Sun.COM hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle, uint8_t rdc) 64*7959SMichael.Speer@Sun.COM { 65*7959SMichael.Speer@Sun.COM rdc_rx_cfg1_t cfg; 66*7959SMichael.Speer@Sun.COM uint32_t count = RXDMA_RESET_TRY_COUNT; 67*7959SMichael.Speer@Sun.COM uint32_t delay_time = RXDMA_RESET_DELAY; 68*7959SMichael.Speer@Sun.COM 69*7959SMichael.Speer@Sun.COM RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 70*7959SMichael.Speer@Sun.COM 71*7959SMichael.Speer@Sun.COM while ((count--) && (cfg.bits.qst == 0)) { 72*7959SMichael.Speer@Sun.COM HXGE_DELAY(delay_time); 73*7959SMichael.Speer@Sun.COM RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 74*7959SMichael.Speer@Sun.COM } 75*7959SMichael.Speer@Sun.COM 76*7959SMichael.Speer@Sun.COM if (cfg.bits.qst == 0) 77*7959SMichael.Speer@Sun.COM return (HPI_FAILURE); 78*7959SMichael.Speer@Sun.COM 79*7959SMichael.Speer@Sun.COM return (HPI_SUCCESS); 80*7959SMichael.Speer@Sun.COM } 816349Sqs148142 826349Sqs148142 /* RX DMA functions */ 836349Sqs148142 static hpi_status_t 846349Sqs148142 hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle, uint8_t rdc, uint8_t op) 856349Sqs148142 { 866349Sqs148142 rdc_rx_cfg1_t cfg; 876349Sqs148142 uint32_t count = RXDMA_RESET_TRY_COUNT; 886349Sqs148142 uint32_t delay_time = RXDMA_RESET_DELAY; 896349Sqs148142 uint32_t error = HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RESET_ERR, rdc); 906349Sqs148142 916349Sqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 926349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 936349Sqs148142 "hpi_rxdma_cfg_rdc_ctl Illegal RDC number %d \n", rdc)); 946349Sqs148142 return (HPI_RXDMA_RDC_INVALID); 956349Sqs148142 } 966349Sqs148142 976349Sqs148142 switch (op) { 986349Sqs148142 case RXDMA_OP_ENABLE: 996349Sqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1006349Sqs148142 cfg.bits.enable = 1; 1016349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 1026349Sqs148142 1036349Sqs148142 HXGE_DELAY(delay_time); 104*7959SMichael.Speer@Sun.COM RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1056349Sqs148142 106*7959SMichael.Speer@Sun.COM while ((count--) && (cfg.bits.qst == 1)) { 107*7959SMichael.Speer@Sun.COM HXGE_DELAY(delay_time); 108*7959SMichael.Speer@Sun.COM RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 109*7959SMichael.Speer@Sun.COM } 110*7959SMichael.Speer@Sun.COM if (cfg.bits.qst == 1) { 111*7959SMichael.Speer@Sun.COM cmn_err(CE_CONT, "hxge rdc(%d): not enabled\n", rdc); 112*7959SMichael.Speer@Sun.COM return (HPI_FAILURE); 113*7959SMichael.Speer@Sun.COM } 1146349Sqs148142 break; 115*7959SMichael.Speer@Sun.COM 1166349Sqs148142 case RXDMA_OP_DISABLE: 1176349Sqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1186349Sqs148142 cfg.bits.enable = 0; 1196349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 1206349Sqs148142 1216349Sqs148142 HXGE_DELAY(delay_time); 122*7959SMichael.Speer@Sun.COM if (hpi_rxdma_cfg_rdc_wait_for_qst(handle, 123*7959SMichael.Speer@Sun.COM rdc) != HPI_SUCCESS) { 1246349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1256349Sqs148142 " hpi_rxdma_cfg_rdc_ctl" 1266349Sqs148142 " RXDMA_OP_DISABLE Failed for RDC %d \n", 1276349Sqs148142 rdc)); 1286349Sqs148142 return (error); 1296349Sqs148142 } 130*7959SMichael.Speer@Sun.COM break; 1316349Sqs148142 1326349Sqs148142 case RXDMA_OP_RESET: 1336349Sqs148142 cfg.value = 0; 1346349Sqs148142 cfg.bits.reset = 1; 1356349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 1366349Sqs148142 HXGE_DELAY(delay_time); 1376349Sqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1386349Sqs148142 1396349Sqs148142 while ((count--) && (cfg.bits.qst == 0)) { 1406349Sqs148142 HXGE_DELAY(delay_time); 1416349Sqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1426349Sqs148142 } 1436349Sqs148142 if (count == 0) { 1446349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1456349Sqs148142 " hpi_rxdma_cfg_rdc_ctl" 1466349Sqs148142 " Reset Failed for RDC %d \n", rdc)); 1476349Sqs148142 return (error); 1486349Sqs148142 } 149*7959SMichael.Speer@Sun.COM break; 1506349Sqs148142 1516349Sqs148142 default: 1526349Sqs148142 return (HPI_RXDMA_SW_PARAM_ERROR); 1536349Sqs148142 } 1546349Sqs148142 1556349Sqs148142 return (HPI_SUCCESS); 1566349Sqs148142 } 1576349Sqs148142 1586349Sqs148142 hpi_status_t 1596349Sqs148142 hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle, uint8_t rdc) 1606349Sqs148142 { 1616349Sqs148142 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_ENABLE)); 1626349Sqs148142 } 1636349Sqs148142 1646349Sqs148142 hpi_status_t 1656349Sqs148142 hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle, uint8_t rdc) 1666349Sqs148142 { 1676349Sqs148142 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_DISABLE)); 1686349Sqs148142 } 1696349Sqs148142 1706349Sqs148142 hpi_status_t 1716349Sqs148142 hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle, uint8_t rdc) 1726349Sqs148142 { 1736349Sqs148142 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_RESET)); 1746349Sqs148142 } 1756349Sqs148142 1766349Sqs148142 static hpi_status_t 1776349Sqs148142 hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle, uint8_t rdc, 1786349Sqs148142 uint8_t op, uint16_t param) 1796349Sqs148142 { 1806349Sqs148142 rdc_rcr_cfg_b_t rcr_cfgb; 1816349Sqs148142 1826349Sqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 1836349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1846349Sqs148142 "rxdma_cfg_rdc_rcr_ctl Illegal RDC number %d \n", rdc)); 1856349Sqs148142 return (HPI_RXDMA_RDC_INVALID); 1866349Sqs148142 } 1876349Sqs148142 1886349Sqs148142 RXDMA_REG_READ64(handle, RDC_RCR_CFG_B, rdc, &rcr_cfgb.value); 1896349Sqs148142 1906349Sqs148142 switch (op) { 1916349Sqs148142 case RCR_TIMEOUT_ENABLE: 1926349Sqs148142 rcr_cfgb.bits.timeout = (uint8_t)param; 1936349Sqs148142 rcr_cfgb.bits.entout = 1; 1946349Sqs148142 break; 1956349Sqs148142 1966349Sqs148142 case RCR_THRESHOLD: 1976349Sqs148142 rcr_cfgb.bits.pthres = param; 1986349Sqs148142 break; 1996349Sqs148142 2006349Sqs148142 case RCR_TIMEOUT_DISABLE: 2016349Sqs148142 rcr_cfgb.bits.entout = 0; 2026349Sqs148142 break; 2036349Sqs148142 2046349Sqs148142 default: 2056349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2066349Sqs148142 "rxdma_cfg_rdc_rcr_ctl Illegal opcode %x \n", op)); 2076349Sqs148142 return (HPI_RXDMA_OPCODE_INVALID(rdc)); 2086349Sqs148142 } 2096349Sqs148142 2106349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value); 2116349Sqs148142 return (HPI_SUCCESS); 2126349Sqs148142 } 2136349Sqs148142 2146349Sqs148142 hpi_status_t 2156349Sqs148142 hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle, uint8_t rdc, 2166349Sqs148142 uint16_t rcr_threshold) 2176349Sqs148142 { 2186349Sqs148142 return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc, 2196349Sqs148142 RCR_THRESHOLD, rcr_threshold)); 2206349Sqs148142 } 2216349Sqs148142 2226349Sqs148142 hpi_status_t 2236349Sqs148142 hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle, uint8_t rdc, 2246349Sqs148142 uint8_t rcr_timeout) 2256349Sqs148142 { 2266349Sqs148142 return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc, 2276349Sqs148142 RCR_TIMEOUT_ENABLE, rcr_timeout)); 2286349Sqs148142 } 2296349Sqs148142 2306349Sqs148142 /* 2316349Sqs148142 * Configure The RDC channel Rcv Buffer Ring 2326349Sqs148142 */ 2336349Sqs148142 hpi_status_t 2346349Sqs148142 hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle, uint8_t rdc, 2356349Sqs148142 rdc_desc_cfg_t *rdc_desc_cfg) 2366349Sqs148142 { 2376349Sqs148142 rdc_rbr_cfg_a_t cfga; 2386349Sqs148142 rdc_rbr_cfg_b_t cfgb; 2396349Sqs148142 rdc_rx_cfg1_t cfg1; 2406349Sqs148142 rdc_rx_cfg2_t cfg2; 2416349Sqs148142 rdc_rcr_cfg_a_t rcr_cfga; 2426349Sqs148142 rdc_rcr_cfg_b_t rcr_cfgb; 2436349Sqs148142 rdc_page_handle_t page_handle; 2446349Sqs148142 2456349Sqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 2466349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2476349Sqs148142 "rxdma_cfg_rdc_ring Illegal RDC number %d \n", rdc)); 2486349Sqs148142 return (HPI_RXDMA_RDC_INVALID); 2496349Sqs148142 } 2506349Sqs148142 2516349Sqs148142 cfga.value = 0; 2526349Sqs148142 cfgb.value = 0; 2536349Sqs148142 cfg1.value = 0; 2546349Sqs148142 cfg2.value = 0; 2556349Sqs148142 page_handle.value = 0; 2566349Sqs148142 2576349Sqs148142 if (rdc_desc_cfg->mbox_enable == 1) { 2586349Sqs148142 cfg1.bits.mbaddr_h = (rdc_desc_cfg->mbox_addr >> 32) & 0xfff; 2596349Sqs148142 cfg2.bits.mbaddr_l = ((rdc_desc_cfg->mbox_addr & 2606349Sqs148142 RXDMA_CFIG2_MBADDR_L_MASK) >> RXDMA_CFIG2_MBADDR_L_SHIFT); 2616349Sqs148142 2626349Sqs148142 /* 2636349Sqs148142 * Only after all the configurations are set, then 2646349Sqs148142 * enable the RDC or else configuration fatal error 2656349Sqs148142 * will be returned (especially if the Hypervisor 2666349Sqs148142 * set up the logical pages with non-zero values. 2676349Sqs148142 * This HPI function only sets up the configuration. 2686349Sqs148142 * Call the enable function to enable the RDMC! 2696349Sqs148142 */ 2706349Sqs148142 } 2716349Sqs148142 2726349Sqs148142 if (rdc_desc_cfg->full_hdr == 1) 2736349Sqs148142 cfg2.bits.full_hdr = 1; 2746349Sqs148142 2756349Sqs148142 if (RXDMA_BUFF_OFFSET_VALID(rdc_desc_cfg->offset)) { 2766349Sqs148142 cfg2.bits.offset = rdc_desc_cfg->offset; 2776349Sqs148142 } else { 2786349Sqs148142 cfg2.bits.offset = SW_OFFSET_NO_OFFSET; 2796349Sqs148142 } 2806349Sqs148142 2816349Sqs148142 /* rbr config */ 2826349Sqs148142 cfga.value = (rdc_desc_cfg->rbr_addr & 2836349Sqs148142 (RBR_CFIG_A_STDADDR_MASK | RBR_CFIG_A_STDADDR_BASE_MASK)); 2846349Sqs148142 2856349Sqs148142 /* The remaining 20 bits in the DMA address form the handle */ 2866349Sqs148142 page_handle.bits.handle = (rdc_desc_cfg->rbr_addr >> 44) && 0xfffff; 2876349Sqs148142 2886349Sqs148142 /* 2896349Sqs148142 * The RBR ring size must be multiple of 64. 2906349Sqs148142 */ 2916349Sqs148142 if ((rdc_desc_cfg->rbr_len < RBR_DEFAULT_MIN_LEN) || 2926349Sqs148142 (rdc_desc_cfg->rbr_len > RBR_DEFAULT_MAX_LEN) || 2936349Sqs148142 (rdc_desc_cfg->rbr_len % 64)) { 2946349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2956349Sqs148142 "hpi_rxdma_cfg_rdc_ring Illegal RBR Queue Length %d \n", 2966349Sqs148142 rdc_desc_cfg->rbr_len)); 2976349Sqs148142 return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RBRSZIE_INVALID, rdc)); 2986349Sqs148142 } 2996349Sqs148142 3006349Sqs148142 /* 3016349Sqs148142 * The lower 6 bits are hardcoded to 0 and the higher 10 bits are 3026349Sqs148142 * stored in len. 3036349Sqs148142 */ 3046349Sqs148142 cfga.bits.len = rdc_desc_cfg->rbr_len >> 6; 3056349Sqs148142 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 3066349Sqs148142 "hpi_rxdma_cfg_rdc_ring CFGA 0x%llx len %d (RBR LEN %d)\n", 3076349Sqs148142 cfga.value, cfga.bits.len, rdc_desc_cfg->rbr_len)); 3086349Sqs148142 3096349Sqs148142 /* 3106349Sqs148142 * bksize is 1 bit 3116349Sqs148142 * Buffer Block Size. b0 - 4K; b1 - 8K. 3126349Sqs148142 */ 3136349Sqs148142 if (rdc_desc_cfg->page_size == SIZE_4KB) 3146349Sqs148142 cfgb.bits.bksize = RBR_BKSIZE_4K; 3156349Sqs148142 else if (rdc_desc_cfg->page_size == SIZE_8KB) 3166349Sqs148142 cfgb.bits.bksize = RBR_BKSIZE_8K; 3176349Sqs148142 else { 3186349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3196349Sqs148142 "rxdma_cfg_rdc_ring blksize: Illegal buffer size %d \n", 3206349Sqs148142 rdc_desc_cfg->page_size)); 3216349Sqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3226349Sqs148142 } 3236349Sqs148142 3246349Sqs148142 /* 3256349Sqs148142 * Size 0 of packet buffer. b00 - 256; b01 - 512; b10 - 1K; b11 - resvd. 3266349Sqs148142 */ 3276349Sqs148142 if (rdc_desc_cfg->valid0) { 3286349Sqs148142 if (rdc_desc_cfg->size0 == SIZE_256B) 3296349Sqs148142 cfgb.bits.bufsz0 = RBR_BUFSZ0_256B; 3306349Sqs148142 else if (rdc_desc_cfg->size0 == SIZE_512B) 3316349Sqs148142 cfgb.bits.bufsz0 = RBR_BUFSZ0_512B; 3326349Sqs148142 else if (rdc_desc_cfg->size0 == SIZE_1KB) 3336349Sqs148142 cfgb.bits.bufsz0 = RBR_BUFSZ0_1K; 3346349Sqs148142 else { 3356349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3366349Sqs148142 " rxdma_cfg_rdc_ring" 3376349Sqs148142 " blksize0: Illegal buffer size %x \n", 3386349Sqs148142 rdc_desc_cfg->size0)); 3396349Sqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3406349Sqs148142 } 3416349Sqs148142 cfgb.bits.vld0 = 1; 3426349Sqs148142 } else { 3436349Sqs148142 cfgb.bits.vld0 = 0; 3446349Sqs148142 } 3456349Sqs148142 3466349Sqs148142 /* 3476349Sqs148142 * Size 1 of packet buffer. b0 - 1K; b1 - 2K. 3486349Sqs148142 */ 3496349Sqs148142 if (rdc_desc_cfg->valid1) { 3506349Sqs148142 if (rdc_desc_cfg->size1 == SIZE_1KB) 3516349Sqs148142 cfgb.bits.bufsz1 = RBR_BUFSZ1_1K; 3526349Sqs148142 else if (rdc_desc_cfg->size1 == SIZE_2KB) 3536349Sqs148142 cfgb.bits.bufsz1 = RBR_BUFSZ1_2K; 3546349Sqs148142 else { 3556349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3566349Sqs148142 " rxdma_cfg_rdc_ring" 3576349Sqs148142 " blksize1: Illegal buffer size %x \n", 3586349Sqs148142 rdc_desc_cfg->size1)); 3596349Sqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3606349Sqs148142 } 3616349Sqs148142 cfgb.bits.vld1 = 1; 3626349Sqs148142 } else { 3636349Sqs148142 cfgb.bits.vld1 = 0; 3646349Sqs148142 } 3656349Sqs148142 3666349Sqs148142 /* 3676349Sqs148142 * Size 2 of packet buffer. b0 - 2K; b1 - 4K. 3686349Sqs148142 */ 3696349Sqs148142 if (rdc_desc_cfg->valid2) { 3706349Sqs148142 if (rdc_desc_cfg->size2 == SIZE_2KB) 3716349Sqs148142 cfgb.bits.bufsz2 = RBR_BUFSZ2_2K; 3726349Sqs148142 else if (rdc_desc_cfg->size2 == SIZE_4KB) 3736349Sqs148142 cfgb.bits.bufsz2 = RBR_BUFSZ2_4K; 3746349Sqs148142 else { 3756349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3766349Sqs148142 " rxdma_cfg_rdc_ring" 3776349Sqs148142 " blksize2: Illegal buffer size %x \n", 3786349Sqs148142 rdc_desc_cfg->size2)); 3796349Sqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3806349Sqs148142 } 3816349Sqs148142 cfgb.bits.vld2 = 1; 3826349Sqs148142 } else { 3836349Sqs148142 cfgb.bits.vld2 = 0; 3846349Sqs148142 } 3856349Sqs148142 3866349Sqs148142 rcr_cfga.value = (rdc_desc_cfg->rcr_addr & 3876349Sqs148142 (RCRCFIG_A_STADDR_MASK | RCRCFIG_A_STADDR_BASE_MASK)); 3886349Sqs148142 3896349Sqs148142 /* 3906349Sqs148142 * The rcr len must be multiple of 32. 3916349Sqs148142 */ 3926349Sqs148142 if ((rdc_desc_cfg->rcr_len < RCR_DEFAULT_MIN_LEN) || 3936349Sqs148142 (rdc_desc_cfg->rcr_len > HXGE_RCR_MAX) || 3946349Sqs148142 (rdc_desc_cfg->rcr_len % 32)) { 3956349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3966349Sqs148142 " rxdma_cfg_rdc_ring Illegal RCR Queue Length %d \n", 3976349Sqs148142 rdc_desc_cfg->rcr_len)); 3986349Sqs148142 return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RCRSZIE_INVALID, rdc)); 3996349Sqs148142 } 4006349Sqs148142 4016349Sqs148142 /* 4026349Sqs148142 * Bits 15:5 of the maximum number of 8B entries in RCR. Bits 4:0 are 4036349Sqs148142 * hard-coded to zero. The maximum size is 2^16 - 32. 4046349Sqs148142 */ 4056349Sqs148142 rcr_cfga.bits.len = rdc_desc_cfg->rcr_len >> 5; 4066349Sqs148142 4076349Sqs148142 rcr_cfgb.value = 0; 4086349Sqs148142 if (rdc_desc_cfg->rcr_timeout_enable == 1) { 4096349Sqs148142 /* check if the rcr timeout value is valid */ 4106349Sqs148142 4116349Sqs148142 if (RXDMA_RCR_TO_VALID(rdc_desc_cfg->rcr_timeout)) { 4126349Sqs148142 rcr_cfgb.bits.timeout = rdc_desc_cfg->rcr_timeout; 4136349Sqs148142 rcr_cfgb.bits.entout = 1; 4146349Sqs148142 } else { 4156349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4166349Sqs148142 " rxdma_cfg_rdc_ring" 4176349Sqs148142 " Illegal RCR Timeout value %d \n", 4186349Sqs148142 rdc_desc_cfg->rcr_timeout)); 4196349Sqs148142 rcr_cfgb.bits.entout = 0; 4206349Sqs148142 } 4216349Sqs148142 } else { 4226349Sqs148142 rcr_cfgb.bits.entout = 0; 4236349Sqs148142 } 4246349Sqs148142 4256349Sqs148142 /* check if the rcr threshold value is valid */ 4266349Sqs148142 if (RXDMA_RCR_THRESH_VALID(rdc_desc_cfg->rcr_threshold)) { 4276349Sqs148142 rcr_cfgb.bits.pthres = rdc_desc_cfg->rcr_threshold; 4286349Sqs148142 } else { 4296349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4306349Sqs148142 " rxdma_cfg_rdc_ring Illegal RCR Threshold value %d \n", 4316349Sqs148142 rdc_desc_cfg->rcr_threshold)); 4326349Sqs148142 rcr_cfgb.bits.pthres = 1; 4336349Sqs148142 } 4346349Sqs148142 4356349Sqs148142 /* now do the actual HW configuration */ 4366349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg1.value); 4376349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG2, rdc, cfg2.value); 4386349Sqs148142 4396349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_A, rdc, cfga.value); 4406349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_B, rdc, cfgb.value); 4416349Sqs148142 4426349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_A, rdc, rcr_cfga.value); 4436349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value); 4446349Sqs148142 4456349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_handle.value); 4466349Sqs148142 4476349Sqs148142 return (HPI_SUCCESS); 4486349Sqs148142 } 4496349Sqs148142 4506349Sqs148142 hpi_status_t 4516349Sqs148142 hpi_rxdma_ring_perr_stat_get(hpi_handle_t handle, 4526349Sqs148142 rdc_pref_par_log_t *pre_log, rdc_pref_par_log_t *sha_log) 4536349Sqs148142 { 4546349Sqs148142 /* 4556349Sqs148142 * Hydra doesn't have details about these errors. 4566349Sqs148142 * It only provides the addresses of the errors. 4576349Sqs148142 */ 4586349Sqs148142 HXGE_REG_RD64(handle, RDC_PREF_PAR_LOG, &pre_log->value); 4596349Sqs148142 HXGE_REG_RD64(handle, RDC_SHADOW_PAR_LOG, &sha_log->value); 4606349Sqs148142 4616349Sqs148142 return (HPI_SUCCESS); 4626349Sqs148142 } 4636349Sqs148142 4646349Sqs148142 4656349Sqs148142 /* system wide conf functions */ 4666349Sqs148142 4676349Sqs148142 hpi_status_t 4686349Sqs148142 hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle, uint16_t count) 4696349Sqs148142 { 4706349Sqs148142 uint64_t offset; 4716349Sqs148142 rdc_clock_div_t clk_div; 4726349Sqs148142 4736349Sqs148142 offset = RDC_CLOCK_DIV; 4746349Sqs148142 4756349Sqs148142 clk_div.value = 0; 4766349Sqs148142 clk_div.bits.count = count; 4776349Sqs148142 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 4786349Sqs148142 " hpi_rxdma_cfg_clock_div_set: add 0x%llx " 4796349Sqs148142 "handle 0x%llx value 0x%llx", 4806349Sqs148142 handle.regp, handle.regh, clk_div.value)); 4816349Sqs148142 4826349Sqs148142 HXGE_REG_WR64(handle, offset, clk_div.value); 4836349Sqs148142 4846349Sqs148142 return (HPI_SUCCESS); 4856349Sqs148142 } 4866349Sqs148142 4876349Sqs148142 4886349Sqs148142 hpi_status_t 4896349Sqs148142 hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle, uint8_t rdc, 4906349Sqs148142 rdc_rbr_qlen_t *rbr_stat) 4916349Sqs148142 { 4926349Sqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 4936349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4946349Sqs148142 " rxdma_rdc_rbr_stat_get Illegal RDC Number %d \n", rdc)); 4956349Sqs148142 return (HPI_RXDMA_RDC_INVALID); 4966349Sqs148142 } 4976349Sqs148142 4986349Sqs148142 RXDMA_REG_READ64(handle, RDC_RBR_QLEN, rdc, &rbr_stat->value); 4996349Sqs148142 return (HPI_SUCCESS); 5006349Sqs148142 } 5016349Sqs148142 5026349Sqs148142 5036349Sqs148142 hpi_status_t 5046349Sqs148142 hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle, uint8_t rdc, 5056349Sqs148142 uint16_t *rcr_qlen) 5066349Sqs148142 { 5076349Sqs148142 rdc_rcr_qlen_t stats; 5086349Sqs148142 5096349Sqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 5106349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5116349Sqs148142 " rxdma_rdc_rcr_qlen_get Illegal RDC Number %d \n", rdc)); 5126349Sqs148142 return (HPI_RXDMA_RDC_INVALID); 5136349Sqs148142 } 5146349Sqs148142 5156349Sqs148142 RXDMA_REG_READ64(handle, RDC_RCR_QLEN, rdc, &stats.value); 5166349Sqs148142 *rcr_qlen = stats.bits.qlen; 5176349Sqs148142 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 5186349Sqs148142 " rxdma_rdc_rcr_qlen_get RDC %d qlen %x qlen %x\n", 5196349Sqs148142 rdc, *rcr_qlen, stats.bits.qlen)); 5206349Sqs148142 return (HPI_SUCCESS); 5216349Sqs148142 } 5226349Sqs148142 5236349Sqs148142 hpi_status_t 5246349Sqs148142 hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle, uint8_t channel) 5256349Sqs148142 { 5266349Sqs148142 rdc_stat_t cs; 5276349Sqs148142 5286349Sqs148142 if (!RXDMA_CHANNEL_VALID(channel)) { 5296349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5306349Sqs148142 " hpi_rxdma_channel_rbr_empty_clear", " channel", channel)); 5316349Sqs148142 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 5326349Sqs148142 } 5336349Sqs148142 5346349Sqs148142 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value); 5356349Sqs148142 cs.bits.rbr_empty = 1; 5366349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value); 5376349Sqs148142 5386349Sqs148142 return (HPI_SUCCESS); 5396349Sqs148142 } 5406349Sqs148142 5416349Sqs148142 /* 5426349Sqs148142 * This function is called to operate on the control and status register. 5436349Sqs148142 */ 5446349Sqs148142 hpi_status_t 5456349Sqs148142 hpi_rxdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 5466349Sqs148142 rdc_stat_t *cs_p) 5476349Sqs148142 { 5486349Sqs148142 int status = HPI_SUCCESS; 5496349Sqs148142 rdc_stat_t cs; 5506349Sqs148142 5516349Sqs148142 if (!RXDMA_CHANNEL_VALID(channel)) { 5526349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5536349Sqs148142 "hpi_rxdma_control_status", "channel", channel)); 5546349Sqs148142 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 5556349Sqs148142 } 5566349Sqs148142 5576349Sqs148142 switch (op_mode) { 5586349Sqs148142 case OP_GET: 5596349Sqs148142 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs_p->value); 5606349Sqs148142 break; 5616349Sqs148142 5626349Sqs148142 case OP_SET: 5636349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs_p->value); 5646349Sqs148142 break; 5656349Sqs148142 5666349Sqs148142 case OP_UPDATE: 5676349Sqs148142 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value); 5686349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, 5696349Sqs148142 cs_p->value | cs.value); 5706349Sqs148142 break; 5716349Sqs148142 5726349Sqs148142 default: 5736349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5746349Sqs148142 "hpi_rxdma_control_status", "control", op_mode)); 5756349Sqs148142 return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel)); 5766349Sqs148142 } 5776349Sqs148142 5786349Sqs148142 return (status); 5796349Sqs148142 } 5806349Sqs148142 5816349Sqs148142 /* 5826349Sqs148142 * This function is called to operate on the event mask 5836349Sqs148142 * register which is used for generating interrupts. 5846349Sqs148142 */ 5856349Sqs148142 hpi_status_t 5866349Sqs148142 hpi_rxdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 5876349Sqs148142 rdc_int_mask_t *mask_p) 5886349Sqs148142 { 5896349Sqs148142 int status = HPI_SUCCESS; 5906349Sqs148142 rdc_int_mask_t mask; 5916349Sqs148142 5926349Sqs148142 if (!RXDMA_CHANNEL_VALID(channel)) { 5936349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5946349Sqs148142 "hpi_rxdma_event_mask", "channel", channel)); 5956349Sqs148142 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 5966349Sqs148142 } 5976349Sqs148142 5986349Sqs148142 switch (op_mode) { 5996349Sqs148142 case OP_GET: 6006349Sqs148142 RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask_p->value); 6016349Sqs148142 break; 6026349Sqs148142 6036349Sqs148142 case OP_SET: 6046349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, mask_p->value); 6056349Sqs148142 break; 6066349Sqs148142 6076349Sqs148142 case OP_UPDATE: 6086349Sqs148142 RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask.value); 6096349Sqs148142 RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, 6106349Sqs148142 mask_p->value | mask.value); 6116349Sqs148142 break; 6126349Sqs148142 6136349Sqs148142 default: 6146349Sqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 6156349Sqs148142 "hpi_rxdma_event_mask", "eventmask", op_mode)); 6166349Sqs148142 return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel)); 6176349Sqs148142 } 6186349Sqs148142 6196349Sqs148142 return (status); 6206349Sqs148142 } 621