19e747589SJerin Jacob /* 29e747589SJerin Jacob * BSD LICENSE 39e747589SJerin Jacob * 49e747589SJerin Jacob * Copyright (C) Cavium, Inc. 2017. All rights reserved. 59e747589SJerin Jacob * 69e747589SJerin Jacob * Redistribution and use in source and binary forms, with or without 79e747589SJerin Jacob * modification, are permitted provided that the following conditions 89e747589SJerin Jacob * are met: 99e747589SJerin Jacob * 109e747589SJerin Jacob * * Redistributions of source code must retain the above copyright 119e747589SJerin Jacob * notice, this list of conditions and the following disclaimer. 129e747589SJerin Jacob * * Redistributions in binary form must reproduce the above copyright 139e747589SJerin Jacob * notice, this list of conditions and the following disclaimer in 149e747589SJerin Jacob * the documentation and/or other materials provided with the 159e747589SJerin Jacob * distribution. 169e747589SJerin Jacob * * Neither the name of Cavium, Inc nor the names of its 179e747589SJerin Jacob * contributors may be used to endorse or promote products derived 189e747589SJerin Jacob * from this software without specific prior written permission. 199e747589SJerin Jacob * 209e747589SJerin Jacob * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 219e747589SJerin Jacob * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 229e747589SJerin Jacob * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 239e747589SJerin Jacob * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 249e747589SJerin Jacob * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 259e747589SJerin Jacob * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 269e747589SJerin Jacob * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 279e747589SJerin Jacob * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 289e747589SJerin Jacob * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 299e747589SJerin Jacob * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 309e747589SJerin Jacob * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 319e747589SJerin Jacob */ 329e747589SJerin Jacob 339e747589SJerin Jacob #include <stdint.h> 349e747589SJerin Jacob #include <stdio.h> 359e747589SJerin Jacob #include <stdlib.h> 369e747589SJerin Jacob #include <unistd.h> 379e747589SJerin Jacob 389e747589SJerin Jacob #include <rte_atomic.h> 399e747589SJerin Jacob #include <rte_common.h> 409e747589SJerin Jacob #include <rte_ethdev.h> 419e747589SJerin Jacob #include <rte_ether.h> 429e747589SJerin Jacob #include <rte_log.h> 439e747589SJerin Jacob #include <rte_mbuf.h> 449e747589SJerin Jacob #include <rte_prefetch.h> 459e747589SJerin Jacob 469e747589SJerin Jacob #include "octeontx_ethdev.h" 479e747589SJerin Jacob #include "octeontx_rxtx.h" 489e747589SJerin Jacob #include "octeontx_logs.h" 499e747589SJerin Jacob 50*20186d43SJerin Jacob /* Packet type table */ 51*20186d43SJerin Jacob #define PTYPE_SIZE OCCTX_PKI_LTYPE_LAST 52*20186d43SJerin Jacob 53*20186d43SJerin Jacob static const uint32_t __rte_cache_aligned 54*20186d43SJerin Jacob ptype_table[PTYPE_SIZE][PTYPE_SIZE][PTYPE_SIZE] = { 55*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_NONE] = RTE_PTYPE_UNKNOWN, 56*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_IPSEC_ESP] = RTE_PTYPE_UNKNOWN, 57*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_IPFRAG] = RTE_PTYPE_L4_FRAG, 58*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_IPCOMP] = RTE_PTYPE_UNKNOWN, 59*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_TCP] = RTE_PTYPE_L4_TCP, 60*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_UDP] = RTE_PTYPE_L4_UDP, 61*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_GRE] = RTE_PTYPE_TUNNEL_GRE, 62*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_UDP_GENEVE] = RTE_PTYPE_TUNNEL_GENEVE, 63*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_UDP_VXLAN] = RTE_PTYPE_TUNNEL_VXLAN, 64*20186d43SJerin Jacob [LC_NONE][LE_NONE][LF_NVGRE] = RTE_PTYPE_TUNNEL_NVGRE, 65*20186d43SJerin Jacob 66*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_NONE] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_UNKNOWN, 67*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_IPSEC_ESP] = 68*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L3_IPV4, 69*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_IPFRAG] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_FRAG, 70*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_IPCOMP] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_UNKNOWN, 71*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_TCP] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP, 72*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_UDP] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP, 73*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_GRE] = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_GRE, 74*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_UDP_GENEVE] = 75*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_GENEVE, 76*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_UDP_VXLAN] = 77*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_VXLAN, 78*20186d43SJerin Jacob [LC_IPV4][LE_NONE][LF_NVGRE] = 79*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_NVGRE, 80*20186d43SJerin Jacob 81*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_NONE] = 82*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_UNKNOWN, 83*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_IPSEC_ESP] = 84*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L3_IPV4, 85*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_IPFRAG] = 86*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_FRAG, 87*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_IPCOMP] = 88*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_UNKNOWN, 89*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_TCP] = 90*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_TCP, 91*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_UDP] = 92*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_L4_UDP, 93*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_GRE] = 94*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_TUNNEL_GRE, 95*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_UDP_GENEVE] = 96*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_TUNNEL_GENEVE, 97*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_UDP_VXLAN] = 98*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_TUNNEL_VXLAN, 99*20186d43SJerin Jacob [LC_IPV4_OPT][LE_NONE][LF_NVGRE] = 100*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4_EXT | RTE_PTYPE_TUNNEL_NVGRE, 101*20186d43SJerin Jacob 102*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_NONE] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_UNKNOWN, 103*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_IPSEC_ESP] = 104*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L3_IPV4, 105*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_IPFRAG] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_FRAG, 106*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_IPCOMP] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_UNKNOWN, 107*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_TCP] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP, 108*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_UDP] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP, 109*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_GRE] = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_TUNNEL_GRE, 110*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_UDP_GENEVE] = 111*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6 | RTE_PTYPE_TUNNEL_GENEVE, 112*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_UDP_VXLAN] = 113*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6 | RTE_PTYPE_TUNNEL_VXLAN, 114*20186d43SJerin Jacob [LC_IPV6][LE_NONE][LF_NVGRE] = 115*20186d43SJerin Jacob RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_NVGRE, 116*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_NONE] = 117*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_UNKNOWN, 118*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_IPSEC_ESP] = 119*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L3_IPV4, 120*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_IPFRAG] = 121*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_FRAG, 122*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_IPCOMP] = 123*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_UNKNOWN, 124*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_TCP] = 125*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_TCP, 126*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_UDP] = 127*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_L4_UDP, 128*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_GRE] = 129*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_TUNNEL_GRE, 130*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_UDP_GENEVE] = 131*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_TUNNEL_GENEVE, 132*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_UDP_VXLAN] = 133*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_TUNNEL_VXLAN, 134*20186d43SJerin Jacob [LC_IPV6_OPT][LE_NONE][LF_NVGRE] = 135*20186d43SJerin Jacob RTE_PTYPE_L3_IPV6_EXT | RTE_PTYPE_TUNNEL_NVGRE, 136*20186d43SJerin Jacob 137*20186d43SJerin Jacob }; 138*20186d43SJerin Jacob 1399e747589SJerin Jacob static __rte_always_inline uint16_t __hot 1409e747589SJerin Jacob __octeontx_xmit_pkts(void *lmtline_va, void *ioreg_va, int64_t *fc_status_va, 1419e747589SJerin Jacob struct rte_mbuf *tx_pkt) 1429e747589SJerin Jacob { 1439e747589SJerin Jacob uint64_t cmd_buf[4]; 1449e747589SJerin Jacob uint16_t gaura_id; 1459e747589SJerin Jacob 1469e747589SJerin Jacob if (unlikely(*((volatile int64_t *)fc_status_va) < 0)) 1479e747589SJerin Jacob return -ENOSPC; 1489e747589SJerin Jacob 1499e747589SJerin Jacob /* Get the gaura Id */ 1509e747589SJerin Jacob gaura_id = octeontx_fpa_bufpool_gpool((uintptr_t)tx_pkt->pool->pool_id); 1519e747589SJerin Jacob 1529e747589SJerin Jacob /* Setup PKO_SEND_HDR_S */ 1539e747589SJerin Jacob cmd_buf[0] = tx_pkt->data_len & 0xffff; 1549e747589SJerin Jacob cmd_buf[1] = 0x0; 1559e747589SJerin Jacob 1569e747589SJerin Jacob /* Set don't free bit if reference count > 1 */ 1579e747589SJerin Jacob if (rte_mbuf_refcnt_read(tx_pkt) > 1) 1589e747589SJerin Jacob cmd_buf[0] |= (1ULL << 58); /* SET DF */ 1599e747589SJerin Jacob 1609e747589SJerin Jacob /* Setup PKO_SEND_GATHER_S */ 1619e747589SJerin Jacob cmd_buf[(1 << 1) | 1] = rte_mbuf_data_dma_addr(tx_pkt); 1629e747589SJerin Jacob cmd_buf[(1 << 1) | 0] = PKO_SEND_GATHER_SUBDC | 1639e747589SJerin Jacob PKO_SEND_GATHER_LDTYPE(0x1ull) | 1649e747589SJerin Jacob PKO_SEND_GATHER_GAUAR((long)gaura_id) | 1659e747589SJerin Jacob tx_pkt->data_len; 1669e747589SJerin Jacob 1679e747589SJerin Jacob octeontx_reg_lmtst(lmtline_va, ioreg_va, cmd_buf, PKO_CMD_SZ); 1689e747589SJerin Jacob 1699e747589SJerin Jacob return 0; 1709e747589SJerin Jacob } 1719e747589SJerin Jacob 1729e747589SJerin Jacob uint16_t __hot 1739e747589SJerin Jacob octeontx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts) 1749e747589SJerin Jacob { 1759e747589SJerin Jacob int count; 1769e747589SJerin Jacob struct octeontx_txq *txq = tx_queue; 1779e747589SJerin Jacob octeontx_dq_t *dq = &txq->dq; 1789e747589SJerin Jacob int res; 1799e747589SJerin Jacob 1809e747589SJerin Jacob count = 0; 1819e747589SJerin Jacob 1829e747589SJerin Jacob while (count < nb_pkts) { 1839e747589SJerin Jacob res = __octeontx_xmit_pkts(dq->lmtline_va, dq->ioreg_va, 1849e747589SJerin Jacob dq->fc_status_va, 1859e747589SJerin Jacob tx_pkts[count]); 1869e747589SJerin Jacob if (res < 0) 1879e747589SJerin Jacob break; 1889e747589SJerin Jacob 1899e747589SJerin Jacob count++; 1909e747589SJerin Jacob } 1919e747589SJerin Jacob 1929e747589SJerin Jacob return count; /* return number of pkts transmitted */ 1939e747589SJerin Jacob } 1942d2c7918SJerin Jacob 1952d2c7918SJerin Jacob uint16_t __hot 1962d2c7918SJerin Jacob octeontx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts) 1972d2c7918SJerin Jacob { 1982d2c7918SJerin Jacob struct rte_mbuf *mbuf; 1992d2c7918SJerin Jacob struct octeontx_rxq *rxq; 2002d2c7918SJerin Jacob struct rte_event ev; 2012d2c7918SJerin Jacob octtx_wqe_t *wqe; 2022d2c7918SJerin Jacob size_t count; 2032d2c7918SJerin Jacob uint16_t valid_event; 2042d2c7918SJerin Jacob 2052d2c7918SJerin Jacob rxq = rx_queue; 2062d2c7918SJerin Jacob count = 0; 2072d2c7918SJerin Jacob while (count < nb_pkts) { 2082d2c7918SJerin Jacob valid_event = rte_event_dequeue_burst(rxq->evdev, 2092d2c7918SJerin Jacob rxq->ev_ports, &ev, 2102d2c7918SJerin Jacob 1, 0); 2112d2c7918SJerin Jacob if (!valid_event) 2122d2c7918SJerin Jacob break; 2132d2c7918SJerin Jacob 2142d2c7918SJerin Jacob wqe = (octtx_wqe_t *)(uintptr_t)ev.u64; 2152d2c7918SJerin Jacob rte_prefetch_non_temporal(wqe); 2162d2c7918SJerin Jacob 2172d2c7918SJerin Jacob /* Get mbuf from wqe */ 2182d2c7918SJerin Jacob mbuf = (struct rte_mbuf *)((uintptr_t)wqe - 2192d2c7918SJerin Jacob OCTTX_PACKET_WQE_SKIP); 220*20186d43SJerin Jacob mbuf->packet_type = 221*20186d43SJerin Jacob ptype_table[wqe->s.w2.lcty][wqe->s.w2.lety][wqe->s.w2.lfty]; 2222d2c7918SJerin Jacob mbuf->data_off = RTE_PTR_DIFF(wqe->s.w3.addr, mbuf->buf_addr); 2232d2c7918SJerin Jacob mbuf->pkt_len = wqe->s.w1.len; 2242d2c7918SJerin Jacob mbuf->data_len = mbuf->pkt_len; 2252d2c7918SJerin Jacob mbuf->nb_segs = 1; 2262d2c7918SJerin Jacob mbuf->ol_flags = 0; 2272d2c7918SJerin Jacob mbuf->port = rxq->port_id; 2282d2c7918SJerin Jacob rte_mbuf_refcnt_set(mbuf, 1); 2292d2c7918SJerin Jacob rx_pkts[count++] = mbuf; 2302d2c7918SJerin Jacob } 2312d2c7918SJerin Jacob 2322d2c7918SJerin Jacob return count; /* return number of pkts received */ 2332d2c7918SJerin Jacob } 234