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