13dec9fcdSqs148142 /* 23dec9fcdSqs148142 * CDDL HEADER START 33dec9fcdSqs148142 * 43dec9fcdSqs148142 * The contents of this file are subject to the terms of the 53dec9fcdSqs148142 * Common Development and Distribution License (the "License"). 63dec9fcdSqs148142 * You may not use this file except in compliance with the License. 73dec9fcdSqs148142 * 83dec9fcdSqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93dec9fcdSqs148142 * or http://www.opensolaris.org/os/licensing. 103dec9fcdSqs148142 * See the License for the specific language governing permissions 113dec9fcdSqs148142 * and limitations under the License. 123dec9fcdSqs148142 * 133dec9fcdSqs148142 * When distributing Covered Code, include this CDDL HEADER in each 143dec9fcdSqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153dec9fcdSqs148142 * If applicable, add the following below this CDDL HEADER, with the 163dec9fcdSqs148142 * fields enclosed by brackets "[]" replaced with your own identifying 173dec9fcdSqs148142 * information: Portions Copyright [yyyy] [name of copyright owner] 183dec9fcdSqs148142 * 193dec9fcdSqs148142 * CDDL HEADER END 203dec9fcdSqs148142 */ 213dec9fcdSqs148142 /* 223dec9fcdSqs148142 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 233dec9fcdSqs148142 * Use is subject to license terms. 243dec9fcdSqs148142 */ 253dec9fcdSqs148142 263dec9fcdSqs148142 #include <hpi_rxdma.h> 273dec9fcdSqs148142 #include <hxge_common.h> 28fe930412Sqs148142 #include <hxge_impl.h> 293dec9fcdSqs148142 303dec9fcdSqs148142 #define RXDMA_RESET_TRY_COUNT 5 313dec9fcdSqs148142 #define RXDMA_RESET_DELAY 5 323dec9fcdSqs148142 333dec9fcdSqs148142 #define RXDMA_OP_DISABLE 0 343dec9fcdSqs148142 #define RXDMA_OP_ENABLE 1 353dec9fcdSqs148142 #define RXDMA_OP_RESET 2 363dec9fcdSqs148142 373dec9fcdSqs148142 #define RCR_TIMEOUT_ENABLE 1 383dec9fcdSqs148142 #define RCR_TIMEOUT_DISABLE 2 393dec9fcdSqs148142 #define RCR_THRESHOLD 4 403dec9fcdSqs148142 413dec9fcdSqs148142 hpi_status_t 423dec9fcdSqs148142 hpi_rxdma_cfg_logical_page_handle(hpi_handle_t handle, uint8_t rdc, 433dec9fcdSqs148142 uint64_t page_handle) 443dec9fcdSqs148142 { 453dec9fcdSqs148142 rdc_page_handle_t page_hdl; 463dec9fcdSqs148142 473dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 483dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 493dec9fcdSqs148142 "rxdma_cfg_logical_page_handle" 503dec9fcdSqs148142 " Illegal RDC number %d \n", rdc)); 513dec9fcdSqs148142 return (HPI_RXDMA_RDC_INVALID); 523dec9fcdSqs148142 } 533dec9fcdSqs148142 543dec9fcdSqs148142 page_hdl.value = 0; 553dec9fcdSqs148142 page_hdl.bits.handle = (uint32_t)page_handle; 563dec9fcdSqs148142 573dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_hdl.value); 583dec9fcdSqs148142 593dec9fcdSqs148142 return (HPI_SUCCESS); 603dec9fcdSqs148142 } 613dec9fcdSqs148142 62*069fd767SMichael Speer hpi_status_t 63*069fd767SMichael Speer hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle, uint8_t rdc) 64*069fd767SMichael Speer { 65*069fd767SMichael Speer rdc_rx_cfg1_t cfg; 66*069fd767SMichael Speer uint32_t count = RXDMA_RESET_TRY_COUNT; 67*069fd767SMichael Speer uint32_t delay_time = RXDMA_RESET_DELAY; 68*069fd767SMichael Speer 69*069fd767SMichael Speer RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 70*069fd767SMichael Speer 71*069fd767SMichael Speer while ((count--) && (cfg.bits.qst == 0)) { 72*069fd767SMichael Speer HXGE_DELAY(delay_time); 73*069fd767SMichael Speer RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 74*069fd767SMichael Speer } 75*069fd767SMichael Speer 76*069fd767SMichael Speer if (cfg.bits.qst == 0) 77*069fd767SMichael Speer return (HPI_FAILURE); 78*069fd767SMichael Speer 79*069fd767SMichael Speer return (HPI_SUCCESS); 80*069fd767SMichael Speer } 813dec9fcdSqs148142 823dec9fcdSqs148142 /* RX DMA functions */ 833dec9fcdSqs148142 static hpi_status_t 843dec9fcdSqs148142 hpi_rxdma_cfg_rdc_ctl(hpi_handle_t handle, uint8_t rdc, uint8_t op) 853dec9fcdSqs148142 { 863dec9fcdSqs148142 rdc_rx_cfg1_t cfg; 873dec9fcdSqs148142 uint32_t count = RXDMA_RESET_TRY_COUNT; 883dec9fcdSqs148142 uint32_t delay_time = RXDMA_RESET_DELAY; 893dec9fcdSqs148142 uint32_t error = HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RESET_ERR, rdc); 903dec9fcdSqs148142 913dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 923dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 933dec9fcdSqs148142 "hpi_rxdma_cfg_rdc_ctl Illegal RDC number %d \n", rdc)); 943dec9fcdSqs148142 return (HPI_RXDMA_RDC_INVALID); 953dec9fcdSqs148142 } 963dec9fcdSqs148142 973dec9fcdSqs148142 switch (op) { 983dec9fcdSqs148142 case RXDMA_OP_ENABLE: 993dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1003dec9fcdSqs148142 cfg.bits.enable = 1; 1013dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 1023dec9fcdSqs148142 1033dec9fcdSqs148142 HXGE_DELAY(delay_time); 104*069fd767SMichael Speer RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1053dec9fcdSqs148142 106*069fd767SMichael Speer while ((count--) && (cfg.bits.qst == 1)) { 107*069fd767SMichael Speer HXGE_DELAY(delay_time); 108*069fd767SMichael Speer RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 109*069fd767SMichael Speer } 110*069fd767SMichael Speer if (cfg.bits.qst == 1) { 111*069fd767SMichael Speer return (HPI_FAILURE); 112*069fd767SMichael Speer } 1133dec9fcdSqs148142 break; 114*069fd767SMichael Speer 1153dec9fcdSqs148142 case RXDMA_OP_DISABLE: 1163dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1173dec9fcdSqs148142 cfg.bits.enable = 0; 1183dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 1193dec9fcdSqs148142 1203dec9fcdSqs148142 HXGE_DELAY(delay_time); 121*069fd767SMichael Speer if (hpi_rxdma_cfg_rdc_wait_for_qst(handle, 122*069fd767SMichael Speer rdc) != HPI_SUCCESS) { 1233dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1243dec9fcdSqs148142 " hpi_rxdma_cfg_rdc_ctl" 1253dec9fcdSqs148142 " RXDMA_OP_DISABLE Failed for RDC %d \n", 1263dec9fcdSqs148142 rdc)); 1273dec9fcdSqs148142 return (error); 1283dec9fcdSqs148142 } 1293dec9fcdSqs148142 break; 130*069fd767SMichael Speer 1313dec9fcdSqs148142 case RXDMA_OP_RESET: 1323dec9fcdSqs148142 cfg.value = 0; 1333dec9fcdSqs148142 cfg.bits.reset = 1; 1343dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value); 1353dec9fcdSqs148142 HXGE_DELAY(delay_time); 1363dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1373dec9fcdSqs148142 1383dec9fcdSqs148142 while ((count--) && (cfg.bits.qst == 0)) { 1393dec9fcdSqs148142 HXGE_DELAY(delay_time); 1403dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value); 1413dec9fcdSqs148142 } 1423dec9fcdSqs148142 if (count == 0) { 1433dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1443dec9fcdSqs148142 " hpi_rxdma_cfg_rdc_ctl" 1453dec9fcdSqs148142 " Reset Failed for RDC %d \n", rdc)); 1463dec9fcdSqs148142 return (error); 1473dec9fcdSqs148142 } 1483dec9fcdSqs148142 break; 149*069fd767SMichael Speer 1503dec9fcdSqs148142 default: 1513dec9fcdSqs148142 return (HPI_RXDMA_SW_PARAM_ERROR); 1523dec9fcdSqs148142 } 1533dec9fcdSqs148142 1543dec9fcdSqs148142 return (HPI_SUCCESS); 1553dec9fcdSqs148142 } 1563dec9fcdSqs148142 1573dec9fcdSqs148142 hpi_status_t 1583dec9fcdSqs148142 hpi_rxdma_cfg_rdc_enable(hpi_handle_t handle, uint8_t rdc) 1593dec9fcdSqs148142 { 1603dec9fcdSqs148142 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_ENABLE)); 1613dec9fcdSqs148142 } 1623dec9fcdSqs148142 1633dec9fcdSqs148142 hpi_status_t 1643dec9fcdSqs148142 hpi_rxdma_cfg_rdc_disable(hpi_handle_t handle, uint8_t rdc) 1653dec9fcdSqs148142 { 1663dec9fcdSqs148142 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_DISABLE)); 1673dec9fcdSqs148142 } 1683dec9fcdSqs148142 1693dec9fcdSqs148142 hpi_status_t 1703dec9fcdSqs148142 hpi_rxdma_cfg_rdc_reset(hpi_handle_t handle, uint8_t rdc) 1713dec9fcdSqs148142 { 1723dec9fcdSqs148142 return (hpi_rxdma_cfg_rdc_ctl(handle, rdc, RXDMA_OP_RESET)); 1733dec9fcdSqs148142 } 1743dec9fcdSqs148142 1753dec9fcdSqs148142 static hpi_status_t 1763dec9fcdSqs148142 hpi_rxdma_cfg_rdc_rcr_ctl(hpi_handle_t handle, uint8_t rdc, 1773dec9fcdSqs148142 uint8_t op, uint16_t param) 1783dec9fcdSqs148142 { 1793dec9fcdSqs148142 rdc_rcr_cfg_b_t rcr_cfgb; 1803dec9fcdSqs148142 1813dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 1823dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1833dec9fcdSqs148142 "rxdma_cfg_rdc_rcr_ctl Illegal RDC number %d \n", rdc)); 1843dec9fcdSqs148142 return (HPI_RXDMA_RDC_INVALID); 1853dec9fcdSqs148142 } 1863dec9fcdSqs148142 1873dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RCR_CFG_B, rdc, &rcr_cfgb.value); 1883dec9fcdSqs148142 1893dec9fcdSqs148142 switch (op) { 1903dec9fcdSqs148142 case RCR_TIMEOUT_ENABLE: 1913dec9fcdSqs148142 rcr_cfgb.bits.timeout = (uint8_t)param; 1923dec9fcdSqs148142 rcr_cfgb.bits.entout = 1; 1933dec9fcdSqs148142 break; 1943dec9fcdSqs148142 1953dec9fcdSqs148142 case RCR_THRESHOLD: 1963dec9fcdSqs148142 rcr_cfgb.bits.pthres = param; 1973dec9fcdSqs148142 break; 1983dec9fcdSqs148142 1993dec9fcdSqs148142 case RCR_TIMEOUT_DISABLE: 2003dec9fcdSqs148142 rcr_cfgb.bits.entout = 0; 2013dec9fcdSqs148142 break; 2023dec9fcdSqs148142 2033dec9fcdSqs148142 default: 2043dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2053dec9fcdSqs148142 "rxdma_cfg_rdc_rcr_ctl Illegal opcode %x \n", op)); 2063dec9fcdSqs148142 return (HPI_RXDMA_OPCODE_INVALID(rdc)); 2073dec9fcdSqs148142 } 2083dec9fcdSqs148142 2093dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value); 2103dec9fcdSqs148142 return (HPI_SUCCESS); 2113dec9fcdSqs148142 } 2123dec9fcdSqs148142 2133dec9fcdSqs148142 hpi_status_t 2143dec9fcdSqs148142 hpi_rxdma_cfg_rdc_rcr_threshold(hpi_handle_t handle, uint8_t rdc, 2153dec9fcdSqs148142 uint16_t rcr_threshold) 2163dec9fcdSqs148142 { 2173dec9fcdSqs148142 return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc, 2183dec9fcdSqs148142 RCR_THRESHOLD, rcr_threshold)); 2193dec9fcdSqs148142 } 2203dec9fcdSqs148142 2213dec9fcdSqs148142 hpi_status_t 2223dec9fcdSqs148142 hpi_rxdma_cfg_rdc_rcr_timeout(hpi_handle_t handle, uint8_t rdc, 2233dec9fcdSqs148142 uint8_t rcr_timeout) 2243dec9fcdSqs148142 { 2253dec9fcdSqs148142 return (hpi_rxdma_cfg_rdc_rcr_ctl(handle, rdc, 2263dec9fcdSqs148142 RCR_TIMEOUT_ENABLE, rcr_timeout)); 2273dec9fcdSqs148142 } 2283dec9fcdSqs148142 2293dec9fcdSqs148142 /* 2303dec9fcdSqs148142 * Configure The RDC channel Rcv Buffer Ring 2313dec9fcdSqs148142 */ 2323dec9fcdSqs148142 hpi_status_t 2333dec9fcdSqs148142 hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle, uint8_t rdc, 2343dec9fcdSqs148142 rdc_desc_cfg_t *rdc_desc_cfg) 2353dec9fcdSqs148142 { 2363dec9fcdSqs148142 rdc_rbr_cfg_a_t cfga; 2373dec9fcdSqs148142 rdc_rbr_cfg_b_t cfgb; 2383dec9fcdSqs148142 rdc_rx_cfg1_t cfg1; 2393dec9fcdSqs148142 rdc_rx_cfg2_t cfg2; 2403dec9fcdSqs148142 rdc_rcr_cfg_a_t rcr_cfga; 2413dec9fcdSqs148142 rdc_rcr_cfg_b_t rcr_cfgb; 2423dec9fcdSqs148142 rdc_page_handle_t page_handle; 2433dec9fcdSqs148142 2443dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 2453dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2463dec9fcdSqs148142 "rxdma_cfg_rdc_ring Illegal RDC number %d \n", rdc)); 2473dec9fcdSqs148142 return (HPI_RXDMA_RDC_INVALID); 2483dec9fcdSqs148142 } 2493dec9fcdSqs148142 2503dec9fcdSqs148142 cfga.value = 0; 2513dec9fcdSqs148142 cfgb.value = 0; 2523dec9fcdSqs148142 cfg1.value = 0; 2533dec9fcdSqs148142 cfg2.value = 0; 2543dec9fcdSqs148142 page_handle.value = 0; 2553dec9fcdSqs148142 2563dec9fcdSqs148142 if (rdc_desc_cfg->mbox_enable == 1) { 2573dec9fcdSqs148142 cfg1.bits.mbaddr_h = (rdc_desc_cfg->mbox_addr >> 32) & 0xfff; 2583dec9fcdSqs148142 cfg2.bits.mbaddr_l = ((rdc_desc_cfg->mbox_addr & 2593dec9fcdSqs148142 RXDMA_CFIG2_MBADDR_L_MASK) >> RXDMA_CFIG2_MBADDR_L_SHIFT); 2603dec9fcdSqs148142 2613dec9fcdSqs148142 /* 2623dec9fcdSqs148142 * Only after all the configurations are set, then 2633dec9fcdSqs148142 * enable the RDC or else configuration fatal error 2643dec9fcdSqs148142 * will be returned (especially if the Hypervisor 2653dec9fcdSqs148142 * set up the logical pages with non-zero values. 2663dec9fcdSqs148142 * This HPI function only sets up the configuration. 2673dec9fcdSqs148142 * Call the enable function to enable the RDMC! 2683dec9fcdSqs148142 */ 2693dec9fcdSqs148142 } 2703dec9fcdSqs148142 2713dec9fcdSqs148142 if (rdc_desc_cfg->full_hdr == 1) 2723dec9fcdSqs148142 cfg2.bits.full_hdr = 1; 2733dec9fcdSqs148142 2743dec9fcdSqs148142 if (RXDMA_BUFF_OFFSET_VALID(rdc_desc_cfg->offset)) { 2753dec9fcdSqs148142 cfg2.bits.offset = rdc_desc_cfg->offset; 2763dec9fcdSqs148142 } else { 2773dec9fcdSqs148142 cfg2.bits.offset = SW_OFFSET_NO_OFFSET; 2783dec9fcdSqs148142 } 2793dec9fcdSqs148142 2803dec9fcdSqs148142 /* rbr config */ 2813dec9fcdSqs148142 cfga.value = (rdc_desc_cfg->rbr_addr & 2823dec9fcdSqs148142 (RBR_CFIG_A_STDADDR_MASK | RBR_CFIG_A_STDADDR_BASE_MASK)); 2833dec9fcdSqs148142 2843dec9fcdSqs148142 /* The remaining 20 bits in the DMA address form the handle */ 2853dec9fcdSqs148142 page_handle.bits.handle = (rdc_desc_cfg->rbr_addr >> 44) && 0xfffff; 2863dec9fcdSqs148142 2873dec9fcdSqs148142 /* 2883dec9fcdSqs148142 * The RBR ring size must be multiple of 64. 2893dec9fcdSqs148142 */ 2903dec9fcdSqs148142 if ((rdc_desc_cfg->rbr_len < RBR_DEFAULT_MIN_LEN) || 2913dec9fcdSqs148142 (rdc_desc_cfg->rbr_len > RBR_DEFAULT_MAX_LEN) || 2923dec9fcdSqs148142 (rdc_desc_cfg->rbr_len % 64)) { 2933dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2943dec9fcdSqs148142 "hpi_rxdma_cfg_rdc_ring Illegal RBR Queue Length %d \n", 2953dec9fcdSqs148142 rdc_desc_cfg->rbr_len)); 2963dec9fcdSqs148142 return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RBRSZIE_INVALID, rdc)); 2973dec9fcdSqs148142 } 2983dec9fcdSqs148142 2993dec9fcdSqs148142 /* 3003dec9fcdSqs148142 * The lower 6 bits are hardcoded to 0 and the higher 10 bits are 3013dec9fcdSqs148142 * stored in len. 3023dec9fcdSqs148142 */ 3033dec9fcdSqs148142 cfga.bits.len = rdc_desc_cfg->rbr_len >> 6; 3043dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 3053dec9fcdSqs148142 "hpi_rxdma_cfg_rdc_ring CFGA 0x%llx len %d (RBR LEN %d)\n", 3063dec9fcdSqs148142 cfga.value, cfga.bits.len, rdc_desc_cfg->rbr_len)); 3073dec9fcdSqs148142 3083dec9fcdSqs148142 /* 3093dec9fcdSqs148142 * bksize is 1 bit 3103dec9fcdSqs148142 * Buffer Block Size. b0 - 4K; b1 - 8K. 3113dec9fcdSqs148142 */ 3123dec9fcdSqs148142 if (rdc_desc_cfg->page_size == SIZE_4KB) 3133dec9fcdSqs148142 cfgb.bits.bksize = RBR_BKSIZE_4K; 3143dec9fcdSqs148142 else if (rdc_desc_cfg->page_size == SIZE_8KB) 3153dec9fcdSqs148142 cfgb.bits.bksize = RBR_BKSIZE_8K; 3163dec9fcdSqs148142 else { 3173dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3183dec9fcdSqs148142 "rxdma_cfg_rdc_ring blksize: Illegal buffer size %d \n", 3193dec9fcdSqs148142 rdc_desc_cfg->page_size)); 3203dec9fcdSqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3213dec9fcdSqs148142 } 3223dec9fcdSqs148142 3233dec9fcdSqs148142 /* 3243dec9fcdSqs148142 * Size 0 of packet buffer. b00 - 256; b01 - 512; b10 - 1K; b11 - resvd. 3253dec9fcdSqs148142 */ 3263dec9fcdSqs148142 if (rdc_desc_cfg->valid0) { 3273dec9fcdSqs148142 if (rdc_desc_cfg->size0 == SIZE_256B) 3283dec9fcdSqs148142 cfgb.bits.bufsz0 = RBR_BUFSZ0_256B; 3293dec9fcdSqs148142 else if (rdc_desc_cfg->size0 == SIZE_512B) 3303dec9fcdSqs148142 cfgb.bits.bufsz0 = RBR_BUFSZ0_512B; 3313dec9fcdSqs148142 else if (rdc_desc_cfg->size0 == SIZE_1KB) 3323dec9fcdSqs148142 cfgb.bits.bufsz0 = RBR_BUFSZ0_1K; 3333dec9fcdSqs148142 else { 3343dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3353dec9fcdSqs148142 " rxdma_cfg_rdc_ring" 3363dec9fcdSqs148142 " blksize0: Illegal buffer size %x \n", 3373dec9fcdSqs148142 rdc_desc_cfg->size0)); 3383dec9fcdSqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3393dec9fcdSqs148142 } 3403dec9fcdSqs148142 cfgb.bits.vld0 = 1; 3413dec9fcdSqs148142 } else { 3423dec9fcdSqs148142 cfgb.bits.vld0 = 0; 3433dec9fcdSqs148142 } 3443dec9fcdSqs148142 3453dec9fcdSqs148142 /* 3463dec9fcdSqs148142 * Size 1 of packet buffer. b0 - 1K; b1 - 2K. 3473dec9fcdSqs148142 */ 3483dec9fcdSqs148142 if (rdc_desc_cfg->valid1) { 3493dec9fcdSqs148142 if (rdc_desc_cfg->size1 == SIZE_1KB) 3503dec9fcdSqs148142 cfgb.bits.bufsz1 = RBR_BUFSZ1_1K; 3513dec9fcdSqs148142 else if (rdc_desc_cfg->size1 == SIZE_2KB) 3523dec9fcdSqs148142 cfgb.bits.bufsz1 = RBR_BUFSZ1_2K; 3533dec9fcdSqs148142 else { 3543dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3553dec9fcdSqs148142 " rxdma_cfg_rdc_ring" 3563dec9fcdSqs148142 " blksize1: Illegal buffer size %x \n", 3573dec9fcdSqs148142 rdc_desc_cfg->size1)); 3583dec9fcdSqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3593dec9fcdSqs148142 } 3603dec9fcdSqs148142 cfgb.bits.vld1 = 1; 3613dec9fcdSqs148142 } else { 3623dec9fcdSqs148142 cfgb.bits.vld1 = 0; 3633dec9fcdSqs148142 } 3643dec9fcdSqs148142 3653dec9fcdSqs148142 /* 3663dec9fcdSqs148142 * Size 2 of packet buffer. b0 - 2K; b1 - 4K. 3673dec9fcdSqs148142 */ 3683dec9fcdSqs148142 if (rdc_desc_cfg->valid2) { 3693dec9fcdSqs148142 if (rdc_desc_cfg->size2 == SIZE_2KB) 3703dec9fcdSqs148142 cfgb.bits.bufsz2 = RBR_BUFSZ2_2K; 3713dec9fcdSqs148142 else if (rdc_desc_cfg->size2 == SIZE_4KB) 3723dec9fcdSqs148142 cfgb.bits.bufsz2 = RBR_BUFSZ2_4K; 3733dec9fcdSqs148142 else { 3743dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3753dec9fcdSqs148142 " rxdma_cfg_rdc_ring" 3763dec9fcdSqs148142 " blksize2: Illegal buffer size %x \n", 3773dec9fcdSqs148142 rdc_desc_cfg->size2)); 3783dec9fcdSqs148142 return (HPI_RXDMA_BUFSZIE_INVALID); 3793dec9fcdSqs148142 } 3803dec9fcdSqs148142 cfgb.bits.vld2 = 1; 3813dec9fcdSqs148142 } else { 3823dec9fcdSqs148142 cfgb.bits.vld2 = 0; 3833dec9fcdSqs148142 } 3843dec9fcdSqs148142 3853dec9fcdSqs148142 rcr_cfga.value = (rdc_desc_cfg->rcr_addr & 3863dec9fcdSqs148142 (RCRCFIG_A_STADDR_MASK | RCRCFIG_A_STADDR_BASE_MASK)); 3873dec9fcdSqs148142 3883dec9fcdSqs148142 /* 3893dec9fcdSqs148142 * The rcr len must be multiple of 32. 3903dec9fcdSqs148142 */ 3913dec9fcdSqs148142 if ((rdc_desc_cfg->rcr_len < RCR_DEFAULT_MIN_LEN) || 3923dec9fcdSqs148142 (rdc_desc_cfg->rcr_len > HXGE_RCR_MAX) || 3933dec9fcdSqs148142 (rdc_desc_cfg->rcr_len % 32)) { 3943dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3953dec9fcdSqs148142 " rxdma_cfg_rdc_ring Illegal RCR Queue Length %d \n", 3963dec9fcdSqs148142 rdc_desc_cfg->rcr_len)); 3973dec9fcdSqs148142 return (HPI_RXDMA_ERROR_ENCODE(HPI_RXDMA_RCRSZIE_INVALID, rdc)); 3983dec9fcdSqs148142 } 3993dec9fcdSqs148142 4003dec9fcdSqs148142 /* 4013dec9fcdSqs148142 * Bits 15:5 of the maximum number of 8B entries in RCR. Bits 4:0 are 4023dec9fcdSqs148142 * hard-coded to zero. The maximum size is 2^16 - 32. 4033dec9fcdSqs148142 */ 4043dec9fcdSqs148142 rcr_cfga.bits.len = rdc_desc_cfg->rcr_len >> 5; 4053dec9fcdSqs148142 4063dec9fcdSqs148142 rcr_cfgb.value = 0; 4073dec9fcdSqs148142 if (rdc_desc_cfg->rcr_timeout_enable == 1) { 4083dec9fcdSqs148142 /* check if the rcr timeout value is valid */ 4093dec9fcdSqs148142 4103dec9fcdSqs148142 if (RXDMA_RCR_TO_VALID(rdc_desc_cfg->rcr_timeout)) { 4113dec9fcdSqs148142 rcr_cfgb.bits.timeout = rdc_desc_cfg->rcr_timeout; 4123dec9fcdSqs148142 rcr_cfgb.bits.entout = 1; 4133dec9fcdSqs148142 } else { 4143dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4153dec9fcdSqs148142 " rxdma_cfg_rdc_ring" 4163dec9fcdSqs148142 " Illegal RCR Timeout value %d \n", 4173dec9fcdSqs148142 rdc_desc_cfg->rcr_timeout)); 4183dec9fcdSqs148142 rcr_cfgb.bits.entout = 0; 4193dec9fcdSqs148142 } 4203dec9fcdSqs148142 } else { 4213dec9fcdSqs148142 rcr_cfgb.bits.entout = 0; 4223dec9fcdSqs148142 } 4233dec9fcdSqs148142 4243dec9fcdSqs148142 /* check if the rcr threshold value is valid */ 4253dec9fcdSqs148142 if (RXDMA_RCR_THRESH_VALID(rdc_desc_cfg->rcr_threshold)) { 4263dec9fcdSqs148142 rcr_cfgb.bits.pthres = rdc_desc_cfg->rcr_threshold; 4273dec9fcdSqs148142 } else { 4283dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4293dec9fcdSqs148142 " rxdma_cfg_rdc_ring Illegal RCR Threshold value %d \n", 4303dec9fcdSqs148142 rdc_desc_cfg->rcr_threshold)); 4313dec9fcdSqs148142 rcr_cfgb.bits.pthres = 1; 4323dec9fcdSqs148142 } 4333dec9fcdSqs148142 4343dec9fcdSqs148142 /* now do the actual HW configuration */ 4353dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg1.value); 4363dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RX_CFG2, rdc, cfg2.value); 4373dec9fcdSqs148142 4383dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_A, rdc, cfga.value); 4393dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RBR_CFG_B, rdc, cfgb.value); 4403dec9fcdSqs148142 4413dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_A, rdc, rcr_cfga.value); 4423dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_RCR_CFG_B, rdc, rcr_cfgb.value); 4433dec9fcdSqs148142 4443dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_PAGE_HANDLE, rdc, page_handle.value); 4453dec9fcdSqs148142 4463dec9fcdSqs148142 return (HPI_SUCCESS); 4473dec9fcdSqs148142 } 4483dec9fcdSqs148142 4493dec9fcdSqs148142 hpi_status_t 4503dec9fcdSqs148142 hpi_rxdma_ring_perr_stat_get(hpi_handle_t handle, 4513dec9fcdSqs148142 rdc_pref_par_log_t *pre_log, rdc_pref_par_log_t *sha_log) 4523dec9fcdSqs148142 { 4533dec9fcdSqs148142 /* 4543dec9fcdSqs148142 * Hydra doesn't have details about these errors. 4553dec9fcdSqs148142 * It only provides the addresses of the errors. 4563dec9fcdSqs148142 */ 4573dec9fcdSqs148142 HXGE_REG_RD64(handle, RDC_PREF_PAR_LOG, &pre_log->value); 4583dec9fcdSqs148142 HXGE_REG_RD64(handle, RDC_SHADOW_PAR_LOG, &sha_log->value); 4593dec9fcdSqs148142 4603dec9fcdSqs148142 return (HPI_SUCCESS); 4613dec9fcdSqs148142 } 4623dec9fcdSqs148142 4633dec9fcdSqs148142 4643dec9fcdSqs148142 /* system wide conf functions */ 4653dec9fcdSqs148142 4663dec9fcdSqs148142 hpi_status_t 4673dec9fcdSqs148142 hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle, uint16_t count) 4683dec9fcdSqs148142 { 4693dec9fcdSqs148142 uint64_t offset; 4703dec9fcdSqs148142 rdc_clock_div_t clk_div; 4713dec9fcdSqs148142 4723dec9fcdSqs148142 offset = RDC_CLOCK_DIV; 4733dec9fcdSqs148142 4743dec9fcdSqs148142 clk_div.value = 0; 4753dec9fcdSqs148142 clk_div.bits.count = count; 4763dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 4773dec9fcdSqs148142 " hpi_rxdma_cfg_clock_div_set: add 0x%llx " 4783dec9fcdSqs148142 "handle 0x%llx value 0x%llx", 4793dec9fcdSqs148142 handle.regp, handle.regh, clk_div.value)); 4803dec9fcdSqs148142 4813dec9fcdSqs148142 HXGE_REG_WR64(handle, offset, clk_div.value); 4823dec9fcdSqs148142 4833dec9fcdSqs148142 return (HPI_SUCCESS); 4843dec9fcdSqs148142 } 4853dec9fcdSqs148142 4863dec9fcdSqs148142 4873dec9fcdSqs148142 hpi_status_t 4883dec9fcdSqs148142 hpi_rxdma_rdc_rbr_stat_get(hpi_handle_t handle, uint8_t rdc, 4893dec9fcdSqs148142 rdc_rbr_qlen_t *rbr_stat) 4903dec9fcdSqs148142 { 4913dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 4923dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4933dec9fcdSqs148142 " rxdma_rdc_rbr_stat_get Illegal RDC Number %d \n", rdc)); 4943dec9fcdSqs148142 return (HPI_RXDMA_RDC_INVALID); 4953dec9fcdSqs148142 } 4963dec9fcdSqs148142 4973dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RBR_QLEN, rdc, &rbr_stat->value); 4983dec9fcdSqs148142 return (HPI_SUCCESS); 4993dec9fcdSqs148142 } 5003dec9fcdSqs148142 5013dec9fcdSqs148142 5023dec9fcdSqs148142 hpi_status_t 5033dec9fcdSqs148142 hpi_rxdma_rdc_rcr_qlen_get(hpi_handle_t handle, uint8_t rdc, 5043dec9fcdSqs148142 uint16_t *rcr_qlen) 5053dec9fcdSqs148142 { 5063dec9fcdSqs148142 rdc_rcr_qlen_t stats; 5073dec9fcdSqs148142 5083dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(rdc)) { 5093dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5103dec9fcdSqs148142 " rxdma_rdc_rcr_qlen_get Illegal RDC Number %d \n", rdc)); 5113dec9fcdSqs148142 return (HPI_RXDMA_RDC_INVALID); 5123dec9fcdSqs148142 } 5133dec9fcdSqs148142 5143dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_RCR_QLEN, rdc, &stats.value); 5153dec9fcdSqs148142 *rcr_qlen = stats.bits.qlen; 5163dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_RDC_CTL, 5173dec9fcdSqs148142 " rxdma_rdc_rcr_qlen_get RDC %d qlen %x qlen %x\n", 5183dec9fcdSqs148142 rdc, *rcr_qlen, stats.bits.qlen)); 5193dec9fcdSqs148142 return (HPI_SUCCESS); 5203dec9fcdSqs148142 } 5213dec9fcdSqs148142 5223dec9fcdSqs148142 hpi_status_t 5233dec9fcdSqs148142 hpi_rxdma_channel_rbr_empty_clear(hpi_handle_t handle, uint8_t channel) 5243dec9fcdSqs148142 { 5253dec9fcdSqs148142 rdc_stat_t cs; 5263dec9fcdSqs148142 5273dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(channel)) { 5283dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5293dec9fcdSqs148142 " hpi_rxdma_channel_rbr_empty_clear", " channel", channel)); 5303dec9fcdSqs148142 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 5313dec9fcdSqs148142 } 5323dec9fcdSqs148142 5333dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value); 5343dec9fcdSqs148142 cs.bits.rbr_empty = 1; 5353dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs.value); 5363dec9fcdSqs148142 5373dec9fcdSqs148142 return (HPI_SUCCESS); 5383dec9fcdSqs148142 } 5393dec9fcdSqs148142 5403dec9fcdSqs148142 /* 5413dec9fcdSqs148142 * This function is called to operate on the control and status register. 5423dec9fcdSqs148142 */ 5433dec9fcdSqs148142 hpi_status_t 5443dec9fcdSqs148142 hpi_rxdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 5453dec9fcdSqs148142 rdc_stat_t *cs_p) 5463dec9fcdSqs148142 { 5473dec9fcdSqs148142 int status = HPI_SUCCESS; 5483dec9fcdSqs148142 rdc_stat_t cs; 5493dec9fcdSqs148142 5503dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(channel)) { 5513dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5523dec9fcdSqs148142 "hpi_rxdma_control_status", "channel", channel)); 5533dec9fcdSqs148142 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 5543dec9fcdSqs148142 } 5553dec9fcdSqs148142 5563dec9fcdSqs148142 switch (op_mode) { 5573dec9fcdSqs148142 case OP_GET: 5583dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs_p->value); 5593dec9fcdSqs148142 break; 5603dec9fcdSqs148142 5613dec9fcdSqs148142 case OP_SET: 5623dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, cs_p->value); 5633dec9fcdSqs148142 break; 5643dec9fcdSqs148142 5653dec9fcdSqs148142 case OP_UPDATE: 5663dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_STAT, channel, &cs.value); 5673dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_STAT, channel, 5683dec9fcdSqs148142 cs_p->value | cs.value); 5693dec9fcdSqs148142 break; 5703dec9fcdSqs148142 5713dec9fcdSqs148142 default: 5723dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5733dec9fcdSqs148142 "hpi_rxdma_control_status", "control", op_mode)); 5743dec9fcdSqs148142 return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel)); 5753dec9fcdSqs148142 } 5763dec9fcdSqs148142 5773dec9fcdSqs148142 return (status); 5783dec9fcdSqs148142 } 5793dec9fcdSqs148142 5803dec9fcdSqs148142 /* 5813dec9fcdSqs148142 * This function is called to operate on the event mask 5823dec9fcdSqs148142 * register which is used for generating interrupts. 5833dec9fcdSqs148142 */ 5843dec9fcdSqs148142 hpi_status_t 5853dec9fcdSqs148142 hpi_rxdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 5863dec9fcdSqs148142 rdc_int_mask_t *mask_p) 5873dec9fcdSqs148142 { 5883dec9fcdSqs148142 int status = HPI_SUCCESS; 5893dec9fcdSqs148142 rdc_int_mask_t mask; 5903dec9fcdSqs148142 5913dec9fcdSqs148142 if (!RXDMA_CHANNEL_VALID(channel)) { 5923dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 5933dec9fcdSqs148142 "hpi_rxdma_event_mask", "channel", channel)); 5943dec9fcdSqs148142 return (HPI_FAILURE | HPI_RXDMA_CHANNEL_INVALID(channel)); 5953dec9fcdSqs148142 } 5963dec9fcdSqs148142 5973dec9fcdSqs148142 switch (op_mode) { 5983dec9fcdSqs148142 case OP_GET: 5993dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask_p->value); 6003dec9fcdSqs148142 break; 6013dec9fcdSqs148142 6023dec9fcdSqs148142 case OP_SET: 6033dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, mask_p->value); 6043dec9fcdSqs148142 break; 6053dec9fcdSqs148142 6063dec9fcdSqs148142 case OP_UPDATE: 6073dec9fcdSqs148142 RXDMA_REG_READ64(handle, RDC_INT_MASK, channel, &mask.value); 6083dec9fcdSqs148142 RXDMA_REG_WRITE64(handle, RDC_INT_MASK, channel, 6093dec9fcdSqs148142 mask_p->value | mask.value); 6103dec9fcdSqs148142 break; 6113dec9fcdSqs148142 6123dec9fcdSqs148142 default: 6133dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 6143dec9fcdSqs148142 "hpi_rxdma_event_mask", "eventmask", op_mode)); 6153dec9fcdSqs148142 return (HPI_FAILURE | HPI_RXDMA_OPCODE_INVALID(channel)); 6163dec9fcdSqs148142 } 6173dec9fcdSqs148142 6183dec9fcdSqs148142 return (status); 6193dec9fcdSqs148142 } 620