Branch data Line data Source code
1 : : /* 2 : : * SPDX-License-Identifier: BSD-3-Clause 3 : : * Copyright(c) 2023 Napatech A/S 4 : : */ 5 : : 6 : : #include <unistd.h> 7 : : #include <stdlib.h> 8 : : #include <stdint.h> 9 : : #include <inttypes.h> 10 : : 11 : : #include <rte_ethdev.h> 12 : : #include <rte_malloc.h> 13 : : 14 : : #include "ntlog.h" 15 : : #include "nt_util.h" 16 : : 17 : : static struct nt_util_vfio_impl vfio_cb; 18 : : 19 : : /* uses usleep which schedules out the calling service */ 20 : 0 : void nthw_os_wait_usec(int val) 21 : : { 22 : 0 : rte_delay_us_sleep(val); 23 : 0 : } 24 : : 25 : : /* spins in a waiting loop calling pause asm instruction uses RDTSC - precise wait */ 26 : 0 : void nthw_os_wait_usec_poll(int val) 27 : : { 28 : 0 : rte_delay_us(val); 29 : 0 : } 30 : : 31 : 0 : uint64_t nthw_os_get_time_monotonic_counter(void) 32 : : { 33 : 0 : return rte_get_timer_cycles(); 34 : : } 35 : : 36 : : /* Allocation size matching minimum alignment of specified size */ 37 [ # # ]: 0 : uint64_t nthw_util_align_size(uint64_t size) 38 : : { 39 : 0 : uint64_t alignment_size = 1ULL << rte_log2_u64(size); 40 : 0 : return alignment_size; 41 : : } 42 : : 43 : 0 : void nthw_util_vfio_init(struct nt_util_vfio_impl *impl) 44 : : { 45 : 0 : vfio_cb = *impl; 46 : 0 : } 47 : : 48 : 0 : struct nt_dma_s *nthw_dma_alloc(uint64_t size, uint64_t align, int numa) 49 : : { 50 : : int res; 51 : : struct nt_dma_s *vfio_addr; 52 : : 53 : 0 : vfio_addr = rte_malloc(NULL, sizeof(struct nt_dma_s), 0); 54 : : 55 [ # # ]: 0 : if (!vfio_addr) { 56 : 0 : NT_LOG(ERR, GENERAL, "VFIO rte_malloc failed"); 57 : 0 : return NULL; 58 : : } 59 : : 60 : 0 : void *addr = rte_malloc_socket(NULL, size, align, numa); 61 : : 62 [ # # ]: 0 : if (!addr) { 63 : 0 : rte_free(vfio_addr); 64 : 0 : NT_LOG(ERR, GENERAL, "VFIO rte_malloc_socket failed"); 65 : 0 : return NULL; 66 : : } 67 : : 68 : 0 : res = vfio_cb.vfio_dma_map(0, addr, &vfio_addr->iova, nthw_util_align_size(size)); 69 : : 70 [ # # ]: 0 : if (res != 0) { 71 : 0 : rte_free(addr); 72 : 0 : rte_free(vfio_addr); 73 : 0 : NT_LOG(ERR, GENERAL, "VFIO nt_dma_map failed"); 74 : 0 : return NULL; 75 : : } 76 : : 77 : 0 : vfio_addr->addr = (uint64_t)addr; 78 : 0 : vfio_addr->size = nthw_util_align_size(size); 79 : : 80 : 0 : NT_LOG(DBG, GENERAL, 81 : : "VFIO DMA alloc addr=%" PRIX64 ", iova=%" PRIX64 82 : : ", size=%" PRIX64 "align=0x%" PRIX64, 83 : : vfio_addr->addr, vfio_addr->iova, vfio_addr->size, align); 84 : : 85 : 0 : return vfio_addr; 86 : : } 87 : : 88 : : /* NOTE: please note the difference between RTE_ETH_SPEED_NUM_xxx and RTE_ETH_LINK_SPEED_xxx */ 89 : 0 : int nthw_link_speed_to_eth_speed_num(enum nt_link_speed_e nt_link_speed) 90 : : { 91 : : int eth_speed_num = RTE_ETH_SPEED_NUM_NONE; 92 : : 93 [ # # # # : 0 : switch (nt_link_speed) { # # # # # ] 94 : : case NT_LINK_SPEED_10M: 95 : : eth_speed_num = RTE_ETH_SPEED_NUM_10M; 96 : : break; 97 : : 98 : 0 : case NT_LINK_SPEED_100M: 99 : : eth_speed_num = RTE_ETH_SPEED_NUM_100M; 100 : 0 : break; 101 : : 102 : 0 : case NT_LINK_SPEED_1G: 103 : : eth_speed_num = RTE_ETH_SPEED_NUM_1G; 104 : 0 : break; 105 : : 106 : 0 : case NT_LINK_SPEED_10G: 107 : : eth_speed_num = RTE_ETH_SPEED_NUM_10G; 108 : 0 : break; 109 : : 110 : 0 : case NT_LINK_SPEED_25G: 111 : : eth_speed_num = RTE_ETH_SPEED_NUM_25G; 112 : 0 : break; 113 : : 114 : 0 : case NT_LINK_SPEED_40G: 115 : : eth_speed_num = RTE_ETH_SPEED_NUM_40G; 116 : 0 : break; 117 : : 118 : 0 : case NT_LINK_SPEED_50G: 119 : : eth_speed_num = RTE_ETH_SPEED_NUM_50G; 120 : 0 : break; 121 : : 122 : 0 : case NT_LINK_SPEED_100G: 123 : : eth_speed_num = RTE_ETH_SPEED_NUM_100G; 124 : 0 : break; 125 : : 126 : 0 : default: 127 : : eth_speed_num = RTE_ETH_SPEED_NUM_NONE; 128 : 0 : break; 129 : : } 130 : : 131 : 0 : return eth_speed_num; 132 : : } 133 : : 134 : 0 : uint32_t nthw_link_speed_capa_to_eth_speed_capa(int nt_link_speed_capa) 135 : : { 136 : : uint32_t eth_speed_capa = 0; 137 : : 138 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_10M) 139 : : eth_speed_capa |= RTE_ETH_LINK_SPEED_10M; 140 : : 141 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_100M) 142 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_100M; 143 : : 144 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_1G) 145 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_1G; 146 : : 147 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_10G) 148 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_10G; 149 : : 150 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_25G) 151 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_25G; 152 : : 153 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_40G) 154 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_40G; 155 : : 156 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_50G) 157 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_50G; 158 : : 159 [ # # ]: 0 : if (nt_link_speed_capa & NT_LINK_SPEED_100G) 160 : 0 : eth_speed_capa |= RTE_ETH_LINK_SPEED_100G; 161 : : 162 : 0 : return eth_speed_capa; 163 : : } 164 : : 165 : 0 : int nthw_link_duplex_to_eth_duplex(enum nt_link_duplex_e nt_link_duplex) 166 : : { 167 : : int eth_link_duplex = 0; 168 : : 169 [ # # ]: 0 : switch (nt_link_duplex) { 170 : 0 : case NT_LINK_DUPLEX_FULL: 171 : : eth_link_duplex = RTE_ETH_LINK_FULL_DUPLEX; 172 : 0 : break; 173 : : 174 : : case NT_LINK_DUPLEX_HALF: 175 : : eth_link_duplex = RTE_ETH_LINK_HALF_DUPLEX; 176 : : break; 177 : : 178 : : case NT_LINK_DUPLEX_UNKNOWN: /* fall-through */ 179 : : default: 180 : : break; 181 : : } 182 : : 183 : 0 : return eth_link_duplex; 184 : : } 185 : : 186 : 0 : int nthw_string_to_u32(const char *key_str __rte_unused, const char *value_str, void *extra_args) 187 : : { 188 [ # # ]: 0 : if (!value_str || !extra_args) 189 : : return -1; 190 : : 191 : 0 : const uint32_t value = strtol(value_str, NULL, 0); 192 : 0 : *(uint32_t *)extra_args = value; 193 : 0 : return 0; 194 : : }