16fc581e9SStephen Hemminger /* SPDX-License-Identifier: BSD-3-Clause 2b3b413f7SBruce Richardson * Copyright (C) IGEL Co.,Ltd. 3b3b413f7SBruce Richardson * All rights reserved. 4b3b413f7SBruce Richardson */ 5b3b413f7SBruce Richardson 672b452c5SDmitry Kozlyuk #include <stdlib.h> 772b452c5SDmitry Kozlyuk 8b3b413f7SBruce Richardson #include <rte_mbuf.h> 9df96fd0dSBruce Richardson #include <ethdev_driver.h> 10df96fd0dSBruce Richardson #include <ethdev_vdev.h> 11b3b413f7SBruce Richardson #include <rte_malloc.h> 12b3b413f7SBruce Richardson #include <rte_memcpy.h> 134851ef2bSDavid Marchand #include <bus_vdev_driver.h> 14b3b413f7SBruce Richardson #include <rte_kvargs.h> 151ccec0a8STomasz Kulasek #include <rte_spinlock.h> 16b3b413f7SBruce Richardson 17b3b413f7SBruce Richardson #define ETH_NULL_PACKET_SIZE_ARG "size" 18b3b413f7SBruce Richardson #define ETH_NULL_PACKET_COPY_ARG "copy" 19f51ecf2fSFerruh Yigit #define ETH_NULL_PACKET_NO_RX_ARG "no-rx" 20b3b413f7SBruce Richardson 214df90194SFerruh Yigit static unsigned int default_packet_size = 64; 224df90194SFerruh Yigit static unsigned int default_packet_copy; 23f51ecf2fSFerruh Yigit static unsigned int default_no_rx; 24b3b413f7SBruce Richardson 25b3b413f7SBruce Richardson static const char *valid_arguments[] = { 26b3b413f7SBruce Richardson ETH_NULL_PACKET_SIZE_ARG, 27b3b413f7SBruce Richardson ETH_NULL_PACKET_COPY_ARG, 28f51ecf2fSFerruh Yigit ETH_NULL_PACKET_NO_RX_ARG, 29b3b413f7SBruce Richardson NULL 30b3b413f7SBruce Richardson }; 31b3b413f7SBruce Richardson 32b3b413f7SBruce Richardson struct pmd_internals; 33b3b413f7SBruce Richardson 34b3b413f7SBruce Richardson struct null_queue { 35b3b413f7SBruce Richardson struct pmd_internals *internals; 36b3b413f7SBruce Richardson 37b3b413f7SBruce Richardson struct rte_mempool *mb_pool; 38b3b413f7SBruce Richardson struct rte_mbuf *dummy_packet; 39b3b413f7SBruce Richardson 40e12a0166STyler Retzlaff RTE_ATOMIC(uint64_t) rx_pkts; 41e12a0166STyler Retzlaff RTE_ATOMIC(uint64_t) tx_pkts; 42b3b413f7SBruce Richardson }; 43b3b413f7SBruce Richardson 44276bb4ceSFerruh Yigit struct pmd_options { 45276bb4ceSFerruh Yigit unsigned int packet_copy; 46276bb4ceSFerruh Yigit unsigned int packet_size; 47f51ecf2fSFerruh Yigit unsigned int no_rx; 48276bb4ceSFerruh Yigit }; 49276bb4ceSFerruh Yigit 50b3b413f7SBruce Richardson struct pmd_internals { 514df90194SFerruh Yigit unsigned int packet_size; 524df90194SFerruh Yigit unsigned int packet_copy; 53f51ecf2fSFerruh Yigit unsigned int no_rx; 54f8244c63SZhiyong Yang uint16_t port_id; 55b3b413f7SBruce Richardson 56dd7c54a6STomasz Kulasek struct null_queue rx_null_queues[RTE_MAX_QUEUES_PER_PORT]; 57dd7c54a6STomasz Kulasek struct null_queue tx_null_queues[RTE_MAX_QUEUES_PER_PORT]; 581ccec0a8STomasz Kulasek 596d13ea8eSOlivier Matz struct rte_ether_addr eth_addr; 601ccec0a8STomasz Kulasek /** Bit mask of RSS offloads, the bit offset also means flow type */ 611ccec0a8STomasz Kulasek uint64_t flow_type_rss_offloads; 621ccec0a8STomasz Kulasek 631ccec0a8STomasz Kulasek rte_spinlock_t rss_lock; 641ccec0a8STomasz Kulasek 651ccec0a8STomasz Kulasek uint16_t reta_size; 66295968d1SFerruh Yigit struct rte_eth_rss_reta_entry64 reta_conf[RTE_ETH_RSS_RETA_SIZE_128 / 67295968d1SFerruh Yigit RTE_ETH_RETA_GROUP_SIZE]; 681ccec0a8STomasz Kulasek 691ccec0a8STomasz Kulasek uint8_t rss_key[40]; /**< 40-byte hash key. */ 70b3b413f7SBruce Richardson }; 71b3b413f7SBruce Richardson static struct rte_eth_link pmd_link = { 72295968d1SFerruh Yigit .link_speed = RTE_ETH_SPEED_NUM_10G, 73295968d1SFerruh Yigit .link_duplex = RTE_ETH_LINK_FULL_DUPLEX, 74295968d1SFerruh Yigit .link_status = RTE_ETH_LINK_DOWN, 75295968d1SFerruh Yigit .link_autoneg = RTE_ETH_LINK_FIXED, 76b3b413f7SBruce Richardson }; 77b3b413f7SBruce Richardson 78eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(eth_null_logtype, NOTICE); 79*2b843cacSDavid Marchand #define RTE_LOGTYPE_ETH_NULL eth_null_logtype 80eb16afb9SStephen Hemminger 81*2b843cacSDavid Marchand #define PMD_LOG(level, ...) \ 82*2b843cacSDavid Marchand RTE_LOG_LINE_PREFIX(level, ETH_NULL, "%s(): ", __func__, __VA_ARGS__) 83eb16afb9SStephen Hemminger 84b3b413f7SBruce Richardson static uint16_t 85b3b413f7SBruce Richardson eth_null_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) 86b3b413f7SBruce Richardson { 87b3b413f7SBruce Richardson int i; 88b3b413f7SBruce Richardson struct null_queue *h = q; 894df90194SFerruh Yigit unsigned int packet_size; 90b3b413f7SBruce Richardson 91b3b413f7SBruce Richardson if ((q == NULL) || (bufs == NULL)) 92b3b413f7SBruce Richardson return 0; 93b3b413f7SBruce Richardson 94b3b413f7SBruce Richardson packet_size = h->internals->packet_size; 954e436ddaSMallesh Koujalagi if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) != 0) 964e436ddaSMallesh Koujalagi return 0; 974e436ddaSMallesh Koujalagi 98b3b413f7SBruce Richardson for (i = 0; i < nb_bufs; i++) { 99b3b413f7SBruce Richardson bufs[i]->data_len = (uint16_t)packet_size; 100b3b413f7SBruce Richardson bufs[i]->pkt_len = packet_size; 1015cf86418SSean Harte bufs[i]->port = h->internals->port_id; 102b3b413f7SBruce Richardson } 103b3b413f7SBruce Richardson 104c8881beeSTyler Retzlaff /* NOTE: review for potential ordering optimization */ 105e12a0166STyler Retzlaff rte_atomic_fetch_add_explicit(&h->rx_pkts, i, rte_memory_order_seq_cst); 106b3b413f7SBruce Richardson 107b3b413f7SBruce Richardson return i; 108b3b413f7SBruce Richardson } 109b3b413f7SBruce Richardson 110b3b413f7SBruce Richardson static uint16_t 111b3b413f7SBruce Richardson eth_null_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) 112b3b413f7SBruce Richardson { 113b3b413f7SBruce Richardson int i; 114b3b413f7SBruce Richardson struct null_queue *h = q; 1154df90194SFerruh Yigit unsigned int packet_size; 116b3b413f7SBruce Richardson 117b3b413f7SBruce Richardson if ((q == NULL) || (bufs == NULL)) 118b3b413f7SBruce Richardson return 0; 119b3b413f7SBruce Richardson 120b3b413f7SBruce Richardson packet_size = h->internals->packet_size; 1214e436ddaSMallesh Koujalagi if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) != 0) 1224e436ddaSMallesh Koujalagi return 0; 1234e436ddaSMallesh Koujalagi 124b3b413f7SBruce Richardson for (i = 0; i < nb_bufs; i++) { 125b3b413f7SBruce Richardson rte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), h->dummy_packet, 126b3b413f7SBruce Richardson packet_size); 127b3b413f7SBruce Richardson bufs[i]->data_len = (uint16_t)packet_size; 128b3b413f7SBruce Richardson bufs[i]->pkt_len = packet_size; 1295cf86418SSean Harte bufs[i]->port = h->internals->port_id; 130b3b413f7SBruce Richardson } 131b3b413f7SBruce Richardson 132c8881beeSTyler Retzlaff /* NOTE: review for potential ordering optimization */ 133e12a0166STyler Retzlaff rte_atomic_fetch_add_explicit(&h->rx_pkts, i, rte_memory_order_seq_cst); 134b3b413f7SBruce Richardson 135b3b413f7SBruce Richardson return i; 136b3b413f7SBruce Richardson } 137b3b413f7SBruce Richardson 138b3b413f7SBruce Richardson static uint16_t 139f51ecf2fSFerruh Yigit eth_null_no_rx(void *q __rte_unused, struct rte_mbuf **bufs __rte_unused, 140f51ecf2fSFerruh Yigit uint16_t nb_bufs __rte_unused) 141f51ecf2fSFerruh Yigit { 142f51ecf2fSFerruh Yigit return 0; 143f51ecf2fSFerruh Yigit } 144f51ecf2fSFerruh Yigit 145f51ecf2fSFerruh Yigit static uint16_t 146b3b413f7SBruce Richardson eth_null_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) 147b3b413f7SBruce Richardson { 148b3b413f7SBruce Richardson int i; 149b3b413f7SBruce Richardson struct null_queue *h = q; 150b3b413f7SBruce Richardson 151b3b413f7SBruce Richardson if ((q == NULL) || (bufs == NULL)) 152b3b413f7SBruce Richardson return 0; 153b3b413f7SBruce Richardson 154b3b413f7SBruce Richardson for (i = 0; i < nb_bufs; i++) 155b3b413f7SBruce Richardson rte_pktmbuf_free(bufs[i]); 156b3b413f7SBruce Richardson 157c8881beeSTyler Retzlaff /* NOTE: review for potential ordering optimization */ 158e12a0166STyler Retzlaff rte_atomic_fetch_add_explicit(&h->tx_pkts, i, rte_memory_order_seq_cst); 159b3b413f7SBruce Richardson 160b3b413f7SBruce Richardson return i; 161b3b413f7SBruce Richardson } 162b3b413f7SBruce Richardson 163b3b413f7SBruce Richardson static uint16_t 164b3b413f7SBruce Richardson eth_null_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs) 165b3b413f7SBruce Richardson { 166b3b413f7SBruce Richardson int i; 167b3b413f7SBruce Richardson struct null_queue *h = q; 1684df90194SFerruh Yigit unsigned int packet_size; 169b3b413f7SBruce Richardson 170b3b413f7SBruce Richardson if ((q == NULL) || (bufs == NULL)) 171b3b413f7SBruce Richardson return 0; 172b3b413f7SBruce Richardson 173b3b413f7SBruce Richardson packet_size = h->internals->packet_size; 174b3b413f7SBruce Richardson for (i = 0; i < nb_bufs; i++) { 175b3b413f7SBruce Richardson rte_memcpy(h->dummy_packet, rte_pktmbuf_mtod(bufs[i], void *), 176b3b413f7SBruce Richardson packet_size); 177b3b413f7SBruce Richardson rte_pktmbuf_free(bufs[i]); 178b3b413f7SBruce Richardson } 179b3b413f7SBruce Richardson 180c8881beeSTyler Retzlaff /* NOTE: review for potential ordering optimization */ 181e12a0166STyler Retzlaff rte_atomic_fetch_add_explicit(&h->tx_pkts, i, rte_memory_order_seq_cst); 182b3b413f7SBruce Richardson 183b3b413f7SBruce Richardson return i; 184b3b413f7SBruce Richardson } 185b3b413f7SBruce Richardson 186b3b413f7SBruce Richardson static int 187c9634e44SFerruh Yigit eth_dev_configure(struct rte_eth_dev *dev __rte_unused) 188c9634e44SFerruh Yigit { 189dd7c54a6STomasz Kulasek return 0; 190dd7c54a6STomasz Kulasek } 191b3b413f7SBruce Richardson 192b3b413f7SBruce Richardson static int 193b3b413f7SBruce Richardson eth_dev_start(struct rte_eth_dev *dev) 194b3b413f7SBruce Richardson { 1959b4b368eSJie Hai uint16_t i; 1969b4b368eSJie Hai 197b3b413f7SBruce Richardson if (dev == NULL) 198b3b413f7SBruce Richardson return -EINVAL; 199b3b413f7SBruce Richardson 200295968d1SFerruh Yigit dev->data->dev_link.link_status = RTE_ETH_LINK_UP; 2019b4b368eSJie Hai 2029b4b368eSJie Hai for (i = 0; i < dev->data->nb_rx_queues; i++) 2039b4b368eSJie Hai dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 2049b4b368eSJie Hai for (i = 0; i < dev->data->nb_tx_queues; i++) 2059b4b368eSJie Hai dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 2069b4b368eSJie Hai 207b3b413f7SBruce Richardson return 0; 208b3b413f7SBruce Richardson } 209b3b413f7SBruce Richardson 21062024eb8SIvan Ilchenko static int 211b3b413f7SBruce Richardson eth_dev_stop(struct rte_eth_dev *dev) 212b3b413f7SBruce Richardson { 2139b4b368eSJie Hai uint16_t i; 2149b4b368eSJie Hai 215b3b413f7SBruce Richardson if (dev == NULL) 21662024eb8SIvan Ilchenko return 0; 217b3b413f7SBruce Richardson 218295968d1SFerruh Yigit dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN; 21962024eb8SIvan Ilchenko 2209b4b368eSJie Hai for (i = 0; i < dev->data->nb_rx_queues; i++) 2219b4b368eSJie Hai dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 2229b4b368eSJie Hai for (i = 0; i < dev->data->nb_tx_queues; i++) 2239b4b368eSJie Hai dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 2249b4b368eSJie Hai 22562024eb8SIvan Ilchenko return 0; 226b3b413f7SBruce Richardson } 227b3b413f7SBruce Richardson 228b3b413f7SBruce Richardson static int 229b3b413f7SBruce Richardson eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id, 230b3b413f7SBruce Richardson uint16_t nb_rx_desc __rte_unused, 231b3b413f7SBruce Richardson unsigned int socket_id __rte_unused, 232b3b413f7SBruce Richardson const struct rte_eth_rxconf *rx_conf __rte_unused, 233b3b413f7SBruce Richardson struct rte_mempool *mb_pool) 234b3b413f7SBruce Richardson { 235b3b413f7SBruce Richardson struct rte_mbuf *dummy_packet; 236b3b413f7SBruce Richardson struct pmd_internals *internals; 2374df90194SFerruh Yigit unsigned int packet_size; 238b3b413f7SBruce Richardson 239b3b413f7SBruce Richardson if ((dev == NULL) || (mb_pool == NULL)) 240b3b413f7SBruce Richardson return -EINVAL; 241b3b413f7SBruce Richardson 242dd7c54a6STomasz Kulasek internals = dev->data->dev_private; 243dd7c54a6STomasz Kulasek 244c9634e44SFerruh Yigit if (rx_queue_id >= dev->data->nb_rx_queues) 245b3b413f7SBruce Richardson return -ENODEV; 246b3b413f7SBruce Richardson 247b3b413f7SBruce Richardson packet_size = internals->packet_size; 248b3b413f7SBruce Richardson 249b3b413f7SBruce Richardson internals->rx_null_queues[rx_queue_id].mb_pool = mb_pool; 250b3b413f7SBruce Richardson dev->data->rx_queues[rx_queue_id] = 251b3b413f7SBruce Richardson &internals->rx_null_queues[rx_queue_id]; 252b3b413f7SBruce Richardson dummy_packet = rte_zmalloc_socket(NULL, 253c9634e44SFerruh Yigit packet_size, 0, dev->data->numa_node); 254b3b413f7SBruce Richardson if (dummy_packet == NULL) 255b3b413f7SBruce Richardson return -ENOMEM; 256b3b413f7SBruce Richardson 257b3b413f7SBruce Richardson internals->rx_null_queues[rx_queue_id].internals = internals; 258b3b413f7SBruce Richardson internals->rx_null_queues[rx_queue_id].dummy_packet = dummy_packet; 259b3b413f7SBruce Richardson 260b3b413f7SBruce Richardson return 0; 261b3b413f7SBruce Richardson } 262b3b413f7SBruce Richardson 263b3b413f7SBruce Richardson static int 264b3b413f7SBruce Richardson eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id, 265b3b413f7SBruce Richardson uint16_t nb_tx_desc __rte_unused, 266b3b413f7SBruce Richardson unsigned int socket_id __rte_unused, 267b3b413f7SBruce Richardson const struct rte_eth_txconf *tx_conf __rte_unused) 268b3b413f7SBruce Richardson { 269b3b413f7SBruce Richardson struct rte_mbuf *dummy_packet; 270b3b413f7SBruce Richardson struct pmd_internals *internals; 2714df90194SFerruh Yigit unsigned int packet_size; 272b3b413f7SBruce Richardson 273b3b413f7SBruce Richardson if (dev == NULL) 274b3b413f7SBruce Richardson return -EINVAL; 275b3b413f7SBruce Richardson 276dd7c54a6STomasz Kulasek internals = dev->data->dev_private; 277dd7c54a6STomasz Kulasek 278c9634e44SFerruh Yigit if (tx_queue_id >= dev->data->nb_tx_queues) 279b3b413f7SBruce Richardson return -ENODEV; 280b3b413f7SBruce Richardson 281b3b413f7SBruce Richardson packet_size = internals->packet_size; 282b3b413f7SBruce Richardson 283b3b413f7SBruce Richardson dev->data->tx_queues[tx_queue_id] = 284b3b413f7SBruce Richardson &internals->tx_null_queues[tx_queue_id]; 285b3b413f7SBruce Richardson dummy_packet = rte_zmalloc_socket(NULL, 286c9634e44SFerruh Yigit packet_size, 0, dev->data->numa_node); 287b3b413f7SBruce Richardson if (dummy_packet == NULL) 288b3b413f7SBruce Richardson return -ENOMEM; 289b3b413f7SBruce Richardson 290b3b413f7SBruce Richardson internals->tx_null_queues[tx_queue_id].internals = internals; 291b3b413f7SBruce Richardson internals->tx_null_queues[tx_queue_id].dummy_packet = dummy_packet; 292b3b413f7SBruce Richardson 293b3b413f7SBruce Richardson return 0; 294b3b413f7SBruce Richardson } 295b3b413f7SBruce Richardson 296e6acdc77SMallesh Koujalagi static int 297e6acdc77SMallesh Koujalagi eth_mtu_set(struct rte_eth_dev *dev __rte_unused, uint16_t mtu __rte_unused) 298e6acdc77SMallesh Koujalagi { 299e6acdc77SMallesh Koujalagi return 0; 300e6acdc77SMallesh Koujalagi } 301b3b413f7SBruce Richardson 302bdad90d1SIvan Ilchenko static int 303b3b413f7SBruce Richardson eth_dev_info(struct rte_eth_dev *dev, 304b3b413f7SBruce Richardson struct rte_eth_dev_info *dev_info) 305b3b413f7SBruce Richardson { 306b3b413f7SBruce Richardson struct pmd_internals *internals; 307b3b413f7SBruce Richardson 308b3b413f7SBruce Richardson if ((dev == NULL) || (dev_info == NULL)) 309bdad90d1SIvan Ilchenko return -EINVAL; 310b3b413f7SBruce Richardson 311b3b413f7SBruce Richardson internals = dev->data->dev_private; 312b3b413f7SBruce Richardson dev_info->max_mac_addrs = 1; 313b3b413f7SBruce Richardson dev_info->max_rx_pktlen = (uint32_t)-1; 314dd7c54a6STomasz Kulasek dev_info->max_rx_queues = RTE_DIM(internals->rx_null_queues); 315dd7c54a6STomasz Kulasek dev_info->max_tx_queues = RTE_DIM(internals->tx_null_queues); 316b3b413f7SBruce Richardson dev_info->min_rx_bufsize = 0; 3171ccec0a8STomasz Kulasek dev_info->reta_size = internals->reta_size; 3181ccec0a8STomasz Kulasek dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads; 319a54db8d3SJie Hai dev_info->hash_key_size = sizeof(internals->rss_key); 320bdad90d1SIvan Ilchenko 321bdad90d1SIvan Ilchenko return 0; 322b3b413f7SBruce Richardson } 323b3b413f7SBruce Richardson 324d5b0924bSMatan Azrad static int 325b3b413f7SBruce Richardson eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats) 326b3b413f7SBruce Richardson { 3274df90194SFerruh Yigit unsigned int i, num_stats; 3289b6076a6SDavid Marchand unsigned long rx_total = 0, tx_total = 0; 329b3b413f7SBruce Richardson const struct pmd_internals *internal; 330b3b413f7SBruce Richardson 331b3b413f7SBruce Richardson if ((dev == NULL) || (igb_stats == NULL)) 332d5b0924bSMatan Azrad return -EINVAL; 333b3b413f7SBruce Richardson 334b3b413f7SBruce Richardson internal = dev->data->dev_private; 3354df90194SFerruh Yigit num_stats = RTE_MIN((unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS, 336c9634e44SFerruh Yigit RTE_MIN(dev->data->nb_rx_queues, 337b34141b2SBruce Richardson RTE_DIM(internal->rx_null_queues))); 338b3b413f7SBruce Richardson for (i = 0; i < num_stats; i++) { 339c8881beeSTyler Retzlaff /* NOTE: review for atomic access */ 340b3b413f7SBruce Richardson igb_stats->q_ipackets[i] = 341c8881beeSTyler Retzlaff internal->rx_null_queues[i].rx_pkts; 342b3b413f7SBruce Richardson rx_total += igb_stats->q_ipackets[i]; 343b3b413f7SBruce Richardson } 344b3b413f7SBruce Richardson 3454df90194SFerruh Yigit num_stats = RTE_MIN((unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS, 346c9634e44SFerruh Yigit RTE_MIN(dev->data->nb_tx_queues, 347b34141b2SBruce Richardson RTE_DIM(internal->tx_null_queues))); 348b3b413f7SBruce Richardson for (i = 0; i < num_stats; i++) { 349c8881beeSTyler Retzlaff /* NOTE: review for atomic access */ 350b3b413f7SBruce Richardson igb_stats->q_opackets[i] = 351c8881beeSTyler Retzlaff internal->tx_null_queues[i].tx_pkts; 352b3b413f7SBruce Richardson tx_total += igb_stats->q_opackets[i]; 353b3b413f7SBruce Richardson } 354b3b413f7SBruce Richardson 355b3b413f7SBruce Richardson igb_stats->ipackets = rx_total; 356b3b413f7SBruce Richardson igb_stats->opackets = tx_total; 357d5b0924bSMatan Azrad 358d5b0924bSMatan Azrad return 0; 359b3b413f7SBruce Richardson } 360b3b413f7SBruce Richardson 3619970a9adSIgor Romanov static int 362b3b413f7SBruce Richardson eth_stats_reset(struct rte_eth_dev *dev) 363b3b413f7SBruce Richardson { 3644df90194SFerruh Yigit unsigned int i; 365b3b413f7SBruce Richardson struct pmd_internals *internal; 366b3b413f7SBruce Richardson 367b3b413f7SBruce Richardson if (dev == NULL) 3689970a9adSIgor Romanov return -EINVAL; 369b3b413f7SBruce Richardson 370b3b413f7SBruce Richardson internal = dev->data->dev_private; 371b34141b2SBruce Richardson for (i = 0; i < RTE_DIM(internal->rx_null_queues); i++) 372c8881beeSTyler Retzlaff /* NOTE: review for atomic access */ 373c8881beeSTyler Retzlaff internal->rx_null_queues[i].rx_pkts = 0; 3749b6076a6SDavid Marchand for (i = 0; i < RTE_DIM(internal->tx_null_queues); i++) 375c8881beeSTyler Retzlaff /* NOTE: review for atomic access */ 376c8881beeSTyler Retzlaff internal->tx_null_queues[i].tx_pkts = 0; 3779970a9adSIgor Romanov 3789970a9adSIgor Romanov return 0; 379b3b413f7SBruce Richardson } 380b3b413f7SBruce Richardson 381b3b413f7SBruce Richardson static void 3827483341aSXueming Li eth_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) 383b3b413f7SBruce Richardson { 3847483341aSXueming Li struct null_queue *nq = dev->data->rx_queues[qid]; 385b3b413f7SBruce Richardson 3867483341aSXueming Li if (nq == NULL) 387b3b413f7SBruce Richardson return; 388b3b413f7SBruce Richardson 3897483341aSXueming Li rte_free(nq->dummy_packet); 3907483341aSXueming Li } 3917483341aSXueming Li 3927483341aSXueming Li static void 3937483341aSXueming Li eth_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) 3947483341aSXueming Li { 3957483341aSXueming Li struct null_queue *nq = dev->data->tx_queues[qid]; 3967483341aSXueming Li 3977483341aSXueming Li if (nq == NULL) 3987483341aSXueming Li return; 3997483341aSXueming Li 400b3b413f7SBruce Richardson rte_free(nq->dummy_packet); 401b3b413f7SBruce Richardson } 402b3b413f7SBruce Richardson 403b3b413f7SBruce Richardson static int 404b3b413f7SBruce Richardson eth_link_update(struct rte_eth_dev *dev __rte_unused, 405b3b413f7SBruce Richardson int wait_to_complete __rte_unused) { return 0; } 406b3b413f7SBruce Richardson 4071ccec0a8STomasz Kulasek static int 4081ccec0a8STomasz Kulasek eth_rss_reta_update(struct rte_eth_dev *dev, 4091ccec0a8STomasz Kulasek struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) 4101ccec0a8STomasz Kulasek { 4111ccec0a8STomasz Kulasek int i, j; 4121ccec0a8STomasz Kulasek struct pmd_internals *internal = dev->data->dev_private; 4131ccec0a8STomasz Kulasek 4141ccec0a8STomasz Kulasek if (reta_size != internal->reta_size) 4151ccec0a8STomasz Kulasek return -EINVAL; 4161ccec0a8STomasz Kulasek 4171ccec0a8STomasz Kulasek rte_spinlock_lock(&internal->rss_lock); 4181ccec0a8STomasz Kulasek 4191ccec0a8STomasz Kulasek /* Copy RETA table */ 420295968d1SFerruh Yigit for (i = 0; i < (internal->reta_size / RTE_ETH_RETA_GROUP_SIZE); i++) { 4211ccec0a8STomasz Kulasek internal->reta_conf[i].mask = reta_conf[i].mask; 422295968d1SFerruh Yigit for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) 4231ccec0a8STomasz Kulasek if ((reta_conf[i].mask >> j) & 0x01) 4241ccec0a8STomasz Kulasek internal->reta_conf[i].reta[j] = reta_conf[i].reta[j]; 4251ccec0a8STomasz Kulasek } 4261ccec0a8STomasz Kulasek 4271ccec0a8STomasz Kulasek rte_spinlock_unlock(&internal->rss_lock); 4281ccec0a8STomasz Kulasek 4291ccec0a8STomasz Kulasek return 0; 4301ccec0a8STomasz Kulasek } 4311ccec0a8STomasz Kulasek 4321ccec0a8STomasz Kulasek static int 4331ccec0a8STomasz Kulasek eth_rss_reta_query(struct rte_eth_dev *dev, 4341ccec0a8STomasz Kulasek struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) 4351ccec0a8STomasz Kulasek { 4361ccec0a8STomasz Kulasek int i, j; 4371ccec0a8STomasz Kulasek struct pmd_internals *internal = dev->data->dev_private; 4381ccec0a8STomasz Kulasek 4391ccec0a8STomasz Kulasek if (reta_size != internal->reta_size) 4401ccec0a8STomasz Kulasek return -EINVAL; 4411ccec0a8STomasz Kulasek 4421ccec0a8STomasz Kulasek rte_spinlock_lock(&internal->rss_lock); 4431ccec0a8STomasz Kulasek 4441ccec0a8STomasz Kulasek /* Copy RETA table */ 445295968d1SFerruh Yigit for (i = 0; i < (internal->reta_size / RTE_ETH_RETA_GROUP_SIZE); i++) { 446295968d1SFerruh Yigit for (j = 0; j < RTE_ETH_RETA_GROUP_SIZE; j++) 4471ccec0a8STomasz Kulasek if ((reta_conf[i].mask >> j) & 0x01) 4481ccec0a8STomasz Kulasek reta_conf[i].reta[j] = internal->reta_conf[i].reta[j]; 4491ccec0a8STomasz Kulasek } 4501ccec0a8STomasz Kulasek 4511ccec0a8STomasz Kulasek rte_spinlock_unlock(&internal->rss_lock); 4521ccec0a8STomasz Kulasek 4531ccec0a8STomasz Kulasek return 0; 4541ccec0a8STomasz Kulasek } 4551ccec0a8STomasz Kulasek 4561ccec0a8STomasz Kulasek static int 4571ccec0a8STomasz Kulasek eth_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) 4581ccec0a8STomasz Kulasek { 4591ccec0a8STomasz Kulasek struct pmd_internals *internal = dev->data->dev_private; 4601ccec0a8STomasz Kulasek 4611ccec0a8STomasz Kulasek rte_spinlock_lock(&internal->rss_lock); 4621ccec0a8STomasz Kulasek 4631ccec0a8STomasz Kulasek if ((rss_conf->rss_hf & internal->flow_type_rss_offloads) != 0) 4641ccec0a8STomasz Kulasek dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 4651ccec0a8STomasz Kulasek rss_conf->rss_hf & internal->flow_type_rss_offloads; 4661ccec0a8STomasz Kulasek 4671ccec0a8STomasz Kulasek if (rss_conf->rss_key) 4681ccec0a8STomasz Kulasek rte_memcpy(internal->rss_key, rss_conf->rss_key, 40); 4691ccec0a8STomasz Kulasek 4701ccec0a8STomasz Kulasek rte_spinlock_unlock(&internal->rss_lock); 4711ccec0a8STomasz Kulasek 4721ccec0a8STomasz Kulasek return 0; 4731ccec0a8STomasz Kulasek } 4741ccec0a8STomasz Kulasek 4751ccec0a8STomasz Kulasek static int 4761ccec0a8STomasz Kulasek eth_rss_hash_conf_get(struct rte_eth_dev *dev, 4771ccec0a8STomasz Kulasek struct rte_eth_rss_conf *rss_conf) 4781ccec0a8STomasz Kulasek { 4791ccec0a8STomasz Kulasek struct pmd_internals *internal = dev->data->dev_private; 4801ccec0a8STomasz Kulasek 4811ccec0a8STomasz Kulasek rte_spinlock_lock(&internal->rss_lock); 4821ccec0a8STomasz Kulasek 4831ccec0a8STomasz Kulasek rss_conf->rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf; 4841ccec0a8STomasz Kulasek if (rss_conf->rss_key) 4851ccec0a8STomasz Kulasek rte_memcpy(rss_conf->rss_key, internal->rss_key, 40); 4861ccec0a8STomasz Kulasek 4871ccec0a8STomasz Kulasek rte_spinlock_unlock(&internal->rss_lock); 4881ccec0a8STomasz Kulasek 4891ccec0a8STomasz Kulasek return 0; 4901ccec0a8STomasz Kulasek } 4911ccec0a8STomasz Kulasek 492caccf8b3SOlivier Matz static int 493c5ac7748SRadu Nicolau eth_mac_address_set(__rte_unused struct rte_eth_dev *dev, 4946d13ea8eSOlivier Matz __rte_unused struct rte_ether_addr *addr) 495c5ac7748SRadu Nicolau { 496caccf8b3SOlivier Matz return 0; 497c5ac7748SRadu Nicolau } 498c5ac7748SRadu Nicolau 499d2fb7164SThomas Monjalon static int 500d2fb7164SThomas Monjalon eth_dev_close(struct rte_eth_dev *dev) 501d2fb7164SThomas Monjalon { 502d2fb7164SThomas Monjalon PMD_LOG(INFO, "Closing null ethdev on NUMA socket %u", 503d2fb7164SThomas Monjalon rte_socket_id()); 504d2fb7164SThomas Monjalon 505d2fb7164SThomas Monjalon if (rte_eal_process_type() != RTE_PROC_PRIMARY) 506d2fb7164SThomas Monjalon return 0; 507d2fb7164SThomas Monjalon 508d2fb7164SThomas Monjalon /* mac_addrs must not be freed alone because part of dev_private */ 509d2fb7164SThomas Monjalon dev->data->mac_addrs = NULL; 510d2fb7164SThomas Monjalon 511d2fb7164SThomas Monjalon return 0; 512d2fb7164SThomas Monjalon } 513d2fb7164SThomas Monjalon 514b3b413f7SBruce Richardson static const struct eth_dev_ops ops = { 515d2fb7164SThomas Monjalon .dev_close = eth_dev_close, 516b3b413f7SBruce Richardson .dev_start = eth_dev_start, 517b3b413f7SBruce Richardson .dev_stop = eth_dev_stop, 518b3b413f7SBruce Richardson .dev_configure = eth_dev_configure, 519b3b413f7SBruce Richardson .dev_infos_get = eth_dev_info, 520b3b413f7SBruce Richardson .rx_queue_setup = eth_rx_queue_setup, 521b3b413f7SBruce Richardson .tx_queue_setup = eth_tx_queue_setup, 5227483341aSXueming Li .rx_queue_release = eth_rx_queue_release, 5237483341aSXueming Li .tx_queue_release = eth_tx_queue_release, 524e6acdc77SMallesh Koujalagi .mtu_set = eth_mtu_set, 525b3b413f7SBruce Richardson .link_update = eth_link_update, 526c5ac7748SRadu Nicolau .mac_addr_set = eth_mac_address_set, 527b3b413f7SBruce Richardson .stats_get = eth_stats_get, 528b3b413f7SBruce Richardson .stats_reset = eth_stats_reset, 5291ccec0a8STomasz Kulasek .reta_update = eth_rss_reta_update, 5301ccec0a8STomasz Kulasek .reta_query = eth_rss_reta_query, 5311ccec0a8STomasz Kulasek .rss_hash_update = eth_rss_hash_update, 5321ccec0a8STomasz Kulasek .rss_hash_conf_get = eth_rss_hash_conf_get 533b3b413f7SBruce Richardson }; 534b3b413f7SBruce Richardson 535c3b047beSJan Blunck static int 536276bb4ceSFerruh Yigit eth_dev_null_create(struct rte_vdev_device *dev, struct pmd_options *args) 537b3b413f7SBruce Richardson { 5384df90194SFerruh Yigit const unsigned int nb_rx_queues = 1; 5394df90194SFerruh Yigit const unsigned int nb_tx_queues = 1; 5405f19dee6SJianfeng Tan struct rte_eth_dev_data *data; 541b3b413f7SBruce Richardson struct pmd_internals *internals = NULL; 542b3b413f7SBruce Richardson struct rte_eth_dev *eth_dev = NULL; 543b3b413f7SBruce Richardson 5441ccec0a8STomasz Kulasek static const uint8_t default_rss_key[40] = { 5451ccec0a8STomasz Kulasek 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 0x41, 0x67, 0x25, 0x3D, 5461ccec0a8STomasz Kulasek 0x43, 0xA3, 0x8F, 0xB0, 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4, 5471ccec0a8STomasz Kulasek 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 0x6A, 0x42, 0xB7, 0x3B, 5481ccec0a8STomasz Kulasek 0xBE, 0xAC, 0x01, 0xFA 5491ccec0a8STomasz Kulasek }; 5501ccec0a8STomasz Kulasek 551050fe6e9SJan Blunck if (dev->device.numa_node == SOCKET_ID_ANY) 552050fe6e9SJan Blunck dev->device.numa_node = rte_socket_id(); 553b3b413f7SBruce Richardson 554eb16afb9SStephen Hemminger PMD_LOG(INFO, "Creating null ethdev on numa socket %u", 555050fe6e9SJan Blunck dev->device.numa_node); 556b3b413f7SBruce Richardson 5575f19dee6SJianfeng Tan eth_dev = rte_eth_vdev_allocate(dev, sizeof(*internals)); 5585f19dee6SJianfeng Tan if (!eth_dev) 559050fe6e9SJan Blunck return -ENOMEM; 560b3b413f7SBruce Richardson 561b3b413f7SBruce Richardson /* now put it all together 562b3b413f7SBruce Richardson * - store queue data in internals, 5638fb9e2bbSBernard Iremonger * - store numa_node info in ethdev data 5648fb9e2bbSBernard Iremonger * - point eth_dev_data to internals 565b3b413f7SBruce Richardson * - and point eth_dev structure to new eth_dev_data structure 566b3b413f7SBruce Richardson */ 567b3b413f7SBruce Richardson /* NOTE: we'll replace the data element, of originally allocated eth_dev 568b3b413f7SBruce Richardson * so the nulls are local per-process */ 569b3b413f7SBruce Richardson 570050fe6e9SJan Blunck internals = eth_dev->data->dev_private; 571276bb4ceSFerruh Yigit internals->packet_size = args->packet_size; 572276bb4ceSFerruh Yigit internals->packet_copy = args->packet_copy; 573f51ecf2fSFerruh Yigit internals->no_rx = args->no_rx; 5745cf86418SSean Harte internals->port_id = eth_dev->data->port_id; 575538da7a1SOlivier Matz rte_eth_random_addr(internals->eth_addr.addr_bytes); 576b3b413f7SBruce Richardson 577295968d1SFerruh Yigit internals->flow_type_rss_offloads = RTE_ETH_RSS_PROTO_MASK; 578295968d1SFerruh Yigit internals->reta_size = RTE_DIM(internals->reta_conf) * RTE_ETH_RETA_GROUP_SIZE; 5791ccec0a8STomasz Kulasek 5801ccec0a8STomasz Kulasek rte_memcpy(internals->rss_key, default_rss_key, 40); 5811ccec0a8STomasz Kulasek 5825f19dee6SJianfeng Tan data = eth_dev->data; 583b3b413f7SBruce Richardson data->nb_rx_queues = (uint16_t)nb_rx_queues; 584b3b413f7SBruce Richardson data->nb_tx_queues = (uint16_t)nb_tx_queues; 585b3b413f7SBruce Richardson data->dev_link = pmd_link; 586c1cd6fb3SMallesh Koujalagi data->mac_addrs = &internals->eth_addr; 587f1652103SCiara Power data->promiscuous = 1; 588f1652103SCiara Power data->all_multicast = 1; 589f30e69b4SFerruh Yigit data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 590b3b413f7SBruce Richardson 591b3b413f7SBruce Richardson eth_dev->dev_ops = &ops; 5926799cfe4SBernard Iremonger 593b3b413f7SBruce Richardson /* finally assign rx and tx ops */ 594276bb4ceSFerruh Yigit if (internals->packet_copy) { 595b3b413f7SBruce Richardson eth_dev->rx_pkt_burst = eth_null_copy_rx; 596b3b413f7SBruce Richardson eth_dev->tx_pkt_burst = eth_null_copy_tx; 597f51ecf2fSFerruh Yigit } else if (internals->no_rx) { 598f51ecf2fSFerruh Yigit eth_dev->rx_pkt_burst = eth_null_no_rx; 599f51ecf2fSFerruh Yigit eth_dev->tx_pkt_burst = eth_null_tx; 600b3b413f7SBruce Richardson } else { 601b3b413f7SBruce Richardson eth_dev->rx_pkt_burst = eth_null_rx; 602b3b413f7SBruce Richardson eth_dev->tx_pkt_burst = eth_null_tx; 603b3b413f7SBruce Richardson } 604b3b413f7SBruce Richardson 605fbe90cddSThomas Monjalon rte_eth_dev_probing_finish(eth_dev); 606b3b413f7SBruce Richardson return 0; 607b3b413f7SBruce Richardson } 608b3b413f7SBruce Richardson 609b3b413f7SBruce Richardson static inline int 610b3b413f7SBruce Richardson get_packet_size_arg(const char *key __rte_unused, 611b3b413f7SBruce Richardson const char *value, void *extra_args) 612b3b413f7SBruce Richardson { 613b3b413f7SBruce Richardson const char *a = value; 6144df90194SFerruh Yigit unsigned int *packet_size = extra_args; 615b3b413f7SBruce Richardson 616b3b413f7SBruce Richardson if ((value == NULL) || (extra_args == NULL)) 617b3b413f7SBruce Richardson return -EINVAL; 618b3b413f7SBruce Richardson 6194df90194SFerruh Yigit *packet_size = (unsigned int)strtoul(a, NULL, 0); 620b3b413f7SBruce Richardson if (*packet_size == UINT_MAX) 621b3b413f7SBruce Richardson return -1; 622b3b413f7SBruce Richardson 623b3b413f7SBruce Richardson return 0; 624b3b413f7SBruce Richardson } 625b3b413f7SBruce Richardson 626b3b413f7SBruce Richardson static inline int 627b3b413f7SBruce Richardson get_packet_copy_arg(const char *key __rte_unused, 628b3b413f7SBruce Richardson const char *value, void *extra_args) 629b3b413f7SBruce Richardson { 630b3b413f7SBruce Richardson const char *a = value; 6314df90194SFerruh Yigit unsigned int *packet_copy = extra_args; 632b3b413f7SBruce Richardson 633b3b413f7SBruce Richardson if ((value == NULL) || (extra_args == NULL)) 634b3b413f7SBruce Richardson return -EINVAL; 635b3b413f7SBruce Richardson 6364df90194SFerruh Yigit *packet_copy = (unsigned int)strtoul(a, NULL, 0); 637b3b413f7SBruce Richardson if (*packet_copy == UINT_MAX) 638b3b413f7SBruce Richardson return -1; 639b3b413f7SBruce Richardson 640b3b413f7SBruce Richardson return 0; 641b3b413f7SBruce Richardson } 642b3b413f7SBruce Richardson 643b3b413f7SBruce Richardson static int 644f51ecf2fSFerruh Yigit get_packet_no_rx_arg(const char *key __rte_unused, 645f51ecf2fSFerruh Yigit const char *value, void *extra_args) 646f51ecf2fSFerruh Yigit { 647f51ecf2fSFerruh Yigit const char *a = value; 648f51ecf2fSFerruh Yigit unsigned int no_rx; 649f51ecf2fSFerruh Yigit 650f51ecf2fSFerruh Yigit if (value == NULL || extra_args == NULL) 651f51ecf2fSFerruh Yigit return -EINVAL; 652f51ecf2fSFerruh Yigit 653f51ecf2fSFerruh Yigit no_rx = (unsigned int)strtoul(a, NULL, 0); 654f51ecf2fSFerruh Yigit if (no_rx != 0 && no_rx != 1) 655f51ecf2fSFerruh Yigit return -1; 656f51ecf2fSFerruh Yigit 657f51ecf2fSFerruh Yigit *(unsigned int *)extra_args = no_rx; 658f51ecf2fSFerruh Yigit return 0; 659f51ecf2fSFerruh Yigit } 660f51ecf2fSFerruh Yigit 661f51ecf2fSFerruh Yigit static int 6625d2aa461SJan Blunck rte_pmd_null_probe(struct rte_vdev_device *dev) 663b3b413f7SBruce Richardson { 6645d2aa461SJan Blunck const char *name, *params; 665276bb4ceSFerruh Yigit struct pmd_options args = { 666276bb4ceSFerruh Yigit .packet_copy = default_packet_copy, 667276bb4ceSFerruh Yigit .packet_size = default_packet_size, 668f51ecf2fSFerruh Yigit .no_rx = default_no_rx, 669276bb4ceSFerruh Yigit }; 670b3b413f7SBruce Richardson struct rte_kvargs *kvlist = NULL; 671ee27edbeSJianfeng Tan struct rte_eth_dev *eth_dev; 672b3b413f7SBruce Richardson int ret; 673b3b413f7SBruce Richardson 6745d2aa461SJan Blunck if (!dev) 675b3b413f7SBruce Richardson return -EINVAL; 676b3b413f7SBruce Richardson 6775d2aa461SJan Blunck name = rte_vdev_device_name(dev); 6785d2aa461SJan Blunck params = rte_vdev_device_args(dev); 679eb16afb9SStephen Hemminger PMD_LOG(INFO, "Initializing pmd_null for %s", name); 680b3b413f7SBruce Richardson 6814852aa8fSQi Zhang if (rte_eal_process_type() == RTE_PROC_SECONDARY) { 682e2f4b250SFerruh Yigit struct pmd_internals *internals; 683ee27edbeSJianfeng Tan eth_dev = rte_eth_dev_attach_secondary(name); 684ee27edbeSJianfeng Tan if (!eth_dev) { 685eb16afb9SStephen Hemminger PMD_LOG(ERR, "Failed to probe %s", name); 686ee27edbeSJianfeng Tan return -1; 687ee27edbeSJianfeng Tan } 688ee27edbeSJianfeng Tan /* TODO: request info from primary to set up Rx and Tx */ 689ee27edbeSJianfeng Tan eth_dev->dev_ops = &ops; 690d1c3ab22SFerruh Yigit eth_dev->device = &dev->device; 691e2f4b250SFerruh Yigit internals = eth_dev->data->dev_private; 692e2f4b250SFerruh Yigit if (internals->packet_copy) { 693bccc77a6SYasufumi Ogawa eth_dev->rx_pkt_burst = eth_null_copy_rx; 694bccc77a6SYasufumi Ogawa eth_dev->tx_pkt_burst = eth_null_copy_tx; 695f51ecf2fSFerruh Yigit } else if (internals->no_rx) { 696f51ecf2fSFerruh Yigit eth_dev->rx_pkt_burst = eth_null_no_rx; 697f51ecf2fSFerruh Yigit eth_dev->tx_pkt_burst = eth_null_tx; 698bccc77a6SYasufumi Ogawa } else { 699bccc77a6SYasufumi Ogawa eth_dev->rx_pkt_burst = eth_null_rx; 700bccc77a6SYasufumi Ogawa eth_dev->tx_pkt_burst = eth_null_tx; 701bccc77a6SYasufumi Ogawa } 702fbe90cddSThomas Monjalon rte_eth_dev_probing_finish(eth_dev); 703ee27edbeSJianfeng Tan return 0; 704ee27edbeSJianfeng Tan } 705ee27edbeSJianfeng Tan 706b3b413f7SBruce Richardson if (params != NULL) { 707b3b413f7SBruce Richardson kvlist = rte_kvargs_parse(params, valid_arguments); 708b3b413f7SBruce Richardson if (kvlist == NULL) 709b3b413f7SBruce Richardson return -1; 710b3b413f7SBruce Richardson 711b3b413f7SBruce Richardson ret = rte_kvargs_process(kvlist, 712b3b413f7SBruce Richardson ETH_NULL_PACKET_SIZE_ARG, 713276bb4ceSFerruh Yigit &get_packet_size_arg, &args.packet_size); 714b3b413f7SBruce Richardson if (ret < 0) 715b3b413f7SBruce Richardson goto free_kvlist; 716b3b413f7SBruce Richardson 717b3b413f7SBruce Richardson 718b3b413f7SBruce Richardson ret = rte_kvargs_process(kvlist, 719b3b413f7SBruce Richardson ETH_NULL_PACKET_COPY_ARG, 720276bb4ceSFerruh Yigit &get_packet_copy_arg, &args.packet_copy); 721b3b413f7SBruce Richardson if (ret < 0) 722b3b413f7SBruce Richardson goto free_kvlist; 723f51ecf2fSFerruh Yigit 724f51ecf2fSFerruh Yigit ret = rte_kvargs_process(kvlist, 725f51ecf2fSFerruh Yigit ETH_NULL_PACKET_NO_RX_ARG, 726f51ecf2fSFerruh Yigit &get_packet_no_rx_arg, &args.no_rx); 727f51ecf2fSFerruh Yigit if (ret < 0) 728f51ecf2fSFerruh Yigit goto free_kvlist; 729f51ecf2fSFerruh Yigit 730f51ecf2fSFerruh Yigit if (args.no_rx && args.packet_copy) { 731f51ecf2fSFerruh Yigit PMD_LOG(ERR, 732f51ecf2fSFerruh Yigit "Both %s and %s arguments at the same time not supported", 733f51ecf2fSFerruh Yigit ETH_NULL_PACKET_COPY_ARG, 734f51ecf2fSFerruh Yigit ETH_NULL_PACKET_NO_RX_ARG); 735f51ecf2fSFerruh Yigit goto free_kvlist; 736f51ecf2fSFerruh Yigit } 737b3b413f7SBruce Richardson } 738b3b413f7SBruce Richardson 739eb16afb9SStephen Hemminger PMD_LOG(INFO, "Configure pmd_null: packet size is %d, " 740276bb4ceSFerruh Yigit "packet copy is %s", args.packet_size, 741276bb4ceSFerruh Yigit args.packet_copy ? "enabled" : "disabled"); 742b3b413f7SBruce Richardson 743276bb4ceSFerruh Yigit ret = eth_dev_null_create(dev, &args); 744b3b413f7SBruce Richardson 745b3b413f7SBruce Richardson free_kvlist: 746b3b413f7SBruce Richardson rte_kvargs_free(kvlist); 747b3b413f7SBruce Richardson return ret; 748b3b413f7SBruce Richardson } 749b3b413f7SBruce Richardson 750b3b413f7SBruce Richardson static int 7515d2aa461SJan Blunck rte_pmd_null_remove(struct rte_vdev_device *dev) 752b3b413f7SBruce Richardson { 753b3b413f7SBruce Richardson struct rte_eth_dev *eth_dev = NULL; 754b3b413f7SBruce Richardson 7555d2aa461SJan Blunck if (!dev) 756b3b413f7SBruce Richardson return -EINVAL; 757b3b413f7SBruce Richardson 7586799cfe4SBernard Iremonger /* find the ethdev entry */ 7595d2aa461SJan Blunck eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev)); 760b3b413f7SBruce Richardson if (eth_dev == NULL) 761d2fb7164SThomas Monjalon return 0; /* port already released */ 762b3b413f7SBruce Richardson 763d2fb7164SThomas Monjalon eth_dev_close(eth_dev); 764b3b413f7SBruce Richardson rte_eth_dev_release_port(eth_dev); 765b3b413f7SBruce Richardson 766b3b413f7SBruce Richardson return 0; 767b3b413f7SBruce Richardson } 768b3b413f7SBruce Richardson 769fe363dd4SJan Viktorin static struct rte_vdev_driver pmd_null_drv = { 77050a3345fSShreyansh Jain .probe = rte_pmd_null_probe, 77150a3345fSShreyansh Jain .remove = rte_pmd_null_remove, 772b3b413f7SBruce Richardson }; 773b3b413f7SBruce Richardson 77401f19227SShreyansh Jain RTE_PMD_REGISTER_VDEV(net_null, pmd_null_drv); 7759fa80cb2SJan Blunck RTE_PMD_REGISTER_ALIAS(net_null, eth_null); 77601f19227SShreyansh Jain RTE_PMD_REGISTER_PARAM_STRING(net_null, 77765eca099SPablo de Lara "size=<int> " 778f51ecf2fSFerruh Yigit "copy=<int> " 779f51ecf2fSFerruh Yigit ETH_NULL_PACKET_NO_RX_ARG "=0|1"); 780