1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2020 Intel Corporation 3 */ 4 5 #include <stdlib.h> 6 #include <string.h> 7 8 #include <rte_mbuf.h> 9 #include <rte_ethdev.h> 10 #include <rte_cryptodev.h> 11 12 #include "obj.h" 13 14 /* 15 * ethdev 16 */ 17 static struct rte_eth_conf port_conf_default = { 18 .link_speeds = 0, 19 .rxmode = { 20 .mq_mode = RTE_ETH_MQ_RX_NONE, 21 .mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */ 22 }, 23 .rx_adv_conf = { 24 .rss_conf = { 25 .rss_key = NULL, 26 .rss_key_len = 40, 27 .rss_hf = 0, 28 }, 29 }, 30 .txmode = { 31 .mq_mode = RTE_ETH_MQ_TX_NONE, 32 }, 33 .lpbk_mode = 0, 34 }; 35 36 #define RETA_CONF_SIZE (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE) 37 38 static int 39 rss_setup(uint16_t port_id, 40 uint16_t reta_size, 41 struct ethdev_params_rss *rss) 42 { 43 struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE]; 44 uint32_t i; 45 int status; 46 47 /* RETA setting */ 48 memset(reta_conf, 0, sizeof(reta_conf)); 49 50 for (i = 0; i < reta_size; i++) 51 reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX; 52 53 for (i = 0; i < reta_size; i++) { 54 uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE; 55 uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE; 56 uint32_t rss_qs_pos = i % rss->n_queues; 57 58 reta_conf[reta_id].reta[reta_pos] = 59 (uint16_t) rss->queue_id[rss_qs_pos]; 60 } 61 62 /* RETA update */ 63 status = rte_eth_dev_rss_reta_update(port_id, 64 reta_conf, 65 reta_size); 66 67 return status; 68 } 69 70 int 71 ethdev_config(const char *name, struct ethdev_params *params) 72 { 73 struct rte_eth_dev_info port_info; 74 struct rte_eth_conf port_conf; 75 struct ethdev_params_rss *rss; 76 struct rte_mempool *mempool; 77 uint32_t i; 78 int numa_node, status; 79 uint16_t port_id = 0; 80 81 /* Check input params */ 82 if (!name || 83 !name[0] || 84 !params || 85 !params->rx.n_queues || 86 !params->rx.queue_size || 87 !params->tx.n_queues || 88 !params->tx.queue_size) 89 return -EINVAL; 90 91 status = rte_eth_dev_get_port_by_name(name, &port_id); 92 if (status) 93 return -EINVAL; 94 95 status = rte_eth_dev_info_get(port_id, &port_info); 96 if (status) 97 return -EINVAL; 98 99 mempool = rte_mempool_lookup(params->rx.mempool_name); 100 if (!mempool) 101 return -EINVAL; 102 103 rss = params->rx.rss; 104 if (rss) { 105 if (!port_info.reta_size || port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512) 106 return -EINVAL; 107 108 if (!rss->n_queues || rss->n_queues >= ETHDEV_RXQ_RSS_MAX) 109 return -EINVAL; 110 111 for (i = 0; i < rss->n_queues; i++) 112 if (rss->queue_id[i] >= port_info.max_rx_queues) 113 return -EINVAL; 114 } 115 116 /* Port */ 117 memcpy(&port_conf, &port_conf_default, sizeof(port_conf)); 118 if (rss) { 119 uint64_t rss_hf = RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP; 120 121 port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS; 122 port_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf & port_info.flow_type_rss_offloads; 123 } 124 125 numa_node = rte_eth_dev_socket_id(port_id); 126 if (numa_node == SOCKET_ID_ANY) 127 numa_node = 0; 128 129 status = rte_eth_dev_configure( 130 port_id, 131 params->rx.n_queues, 132 params->tx.n_queues, 133 &port_conf); 134 135 if (status < 0) 136 return -EINVAL; 137 138 if (params->promiscuous) { 139 status = rte_eth_promiscuous_enable(port_id); 140 if (status) 141 return -EINVAL; 142 } 143 144 /* Port RX */ 145 for (i = 0; i < params->rx.n_queues; i++) { 146 status = rte_eth_rx_queue_setup( 147 port_id, 148 i, 149 params->rx.queue_size, 150 numa_node, 151 NULL, 152 mempool); 153 154 if (status < 0) 155 return -EINVAL; 156 } 157 158 /* Port TX */ 159 for (i = 0; i < params->tx.n_queues; i++) { 160 status = rte_eth_tx_queue_setup( 161 port_id, 162 i, 163 params->tx.queue_size, 164 numa_node, 165 NULL); 166 167 if (status < 0) 168 return -EINVAL; 169 } 170 171 /* Port start */ 172 status = rte_eth_dev_start(port_id); 173 if (status < 0) 174 return -EINVAL; 175 176 if (rss) { 177 status = rss_setup(port_id, port_info.reta_size, rss); 178 179 if (status) { 180 rte_eth_dev_stop(port_id); 181 return -EINVAL; 182 } 183 } 184 185 /* Port link up */ 186 status = rte_eth_dev_set_link_up(port_id); 187 if ((status < 0) && (status != -ENOTSUP)) { 188 rte_eth_dev_stop(port_id); 189 return -EINVAL; 190 } 191 192 return 0; 193 } 194 195 /* 196 * cryptodev 197 */ 198 int 199 cryptodev_config(const char *name, struct cryptodev_params *params) 200 { 201 struct rte_cryptodev_info dev_info; 202 struct rte_cryptodev_config dev_conf; 203 struct rte_cryptodev_qp_conf queue_conf; 204 uint8_t dev_id; 205 uint32_t socket_id, i; 206 int status; 207 208 /* Check input parameters. */ 209 if (!name || 210 !params->n_queue_pairs || 211 !params->queue_size) 212 return -EINVAL; 213 214 /* Find the crypto device. */ 215 status = rte_cryptodev_get_dev_id(name); 216 if (status < 0) 217 return -EINVAL; 218 219 dev_id = (uint8_t)status; 220 221 rte_cryptodev_info_get(dev_id, &dev_info); 222 if (params->n_queue_pairs > dev_info.max_nb_queue_pairs) 223 return -EINVAL; 224 225 socket_id = rte_cryptodev_socket_id(dev_id); 226 227 /* Configure the crypto device. */ 228 memset(&dev_conf, 0, sizeof(dev_conf)); 229 dev_conf.socket_id = socket_id; 230 dev_conf.nb_queue_pairs = params->n_queue_pairs; 231 dev_conf.ff_disable = 0; 232 233 status = rte_cryptodev_configure(dev_id, &dev_conf); 234 if (status) 235 return status; 236 237 /* Configure the crypto device queue pairs. */ 238 memset(&queue_conf, 0, sizeof(queue_conf)); 239 queue_conf.nb_descriptors = params->queue_size; 240 queue_conf.mp_session = NULL; 241 242 for (i = 0; i < params->n_queue_pairs; i++) { 243 status = rte_cryptodev_queue_pair_setup(dev_id, i, &queue_conf, socket_id); 244 if (status) 245 return status; 246 } 247 248 /* Start the crypto device. */ 249 status = rte_cryptodev_start(dev_id); 250 if (status) 251 return status; 252 253 return 0; 254 } 255