b86d7da920d45f8e6b1961d059f56fe0a06b963c
[dpdk.git] / drivers / net / memif / rte_eth_memif.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2018-2019 Cisco Systems, Inc.  All rights reserved.
3  */
4
5 #include <stdlib.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11 #include <sys/ioctl.h>
12 #include <sys/mman.h>
13 #include <linux/if_ether.h>
14 #include <errno.h>
15 #include <sys/eventfd.h>
16
17 #include <rte_version.h>
18 #include <rte_mbuf.h>
19 #include <rte_ether.h>
20 #include <rte_ethdev_driver.h>
21 #include <rte_ethdev_vdev.h>
22 #include <rte_malloc.h>
23 #include <rte_kvargs.h>
24 #include <rte_bus_vdev.h>
25 #include <rte_string_fns.h>
26
27 #include "rte_eth_memif.h"
28 #include "memif_socket.h"
29
30 #define ETH_MEMIF_ID_ARG                "id"
31 #define ETH_MEMIF_ROLE_ARG              "role"
32 #define ETH_MEMIF_PKT_BUFFER_SIZE_ARG   "bsize"
33 #define ETH_MEMIF_RING_SIZE_ARG         "rsize"
34 #define ETH_MEMIF_SOCKET_ARG            "socket"
35 #define ETH_MEMIF_MAC_ARG               "mac"
36 #define ETH_MEMIF_ZC_ARG                "zero-copy"
37 #define ETH_MEMIF_SECRET_ARG            "secret"
38
39 static const char * const valid_arguments[] = {
40         ETH_MEMIF_ID_ARG,
41         ETH_MEMIF_ROLE_ARG,
42         ETH_MEMIF_PKT_BUFFER_SIZE_ARG,
43         ETH_MEMIF_RING_SIZE_ARG,
44         ETH_MEMIF_SOCKET_ARG,
45         ETH_MEMIF_MAC_ARG,
46         ETH_MEMIF_ZC_ARG,
47         ETH_MEMIF_SECRET_ARG,
48         NULL
49 };
50
51 #define MEMIF_MP_SEND_REGION            "memif_mp_send_region"
52
53 const char *
54 memif_version(void)
55 {
56         return ("memif-" RTE_STR(MEMIF_VERSION_MAJOR) "." RTE_STR(MEMIF_VERSION_MINOR));
57 }
58
59 /* Message header to synchronize regions */
60 struct mp_region_msg {
61         char port_name[RTE_DEV_NAME_MAX_LEN];
62         memif_region_index_t idx;
63         memif_region_size_t size;
64 };
65
66 static int
67 memif_mp_send_region(const struct rte_mp_msg *msg, const void *peer)
68 {
69         struct rte_eth_dev *dev;
70         struct pmd_process_private *proc_private;
71         const struct mp_region_msg *msg_param = (const struct mp_region_msg *)msg->param;
72         struct rte_mp_msg reply;
73         struct mp_region_msg *reply_param = (struct mp_region_msg *)reply.param;
74         uint16_t port_id;
75         int ret;
76
77         /* Get requested port */
78         ret = rte_eth_dev_get_port_by_name(msg_param->port_name, &port_id);
79         if (ret) {
80                 MIF_LOG(ERR, "Failed to get port id for %s",
81                         msg_param->port_name);
82                 return -1;
83         }
84         dev = &rte_eth_devices[port_id];
85         proc_private = dev->process_private;
86
87         memset(&reply, 0, sizeof(reply));
88         strlcpy(reply.name, msg->name, sizeof(reply.name));
89         reply_param->idx = msg_param->idx;
90         if (proc_private->regions[msg_param->idx] != NULL) {
91                 reply_param->size = proc_private->regions[msg_param->idx]->region_size;
92                 reply.fds[0] = proc_private->regions[msg_param->idx]->fd;
93                 reply.num_fds = 1;
94         }
95         reply.len_param = sizeof(*reply_param);
96         if (rte_mp_reply(&reply, peer) < 0) {
97                 MIF_LOG(ERR, "Failed to reply to an add region request");
98                 return -1;
99         }
100
101         return 0;
102 }
103
104 /*
105  * Request regions
106  * Called by secondary process, when ports link status goes up.
107  */
108 static int
109 memif_mp_request_regions(struct rte_eth_dev *dev)
110 {
111         int ret, i;
112         struct timespec timeout = {.tv_sec = 5, .tv_nsec = 0};
113         struct rte_mp_msg msg, *reply;
114         struct rte_mp_reply replies;
115         struct mp_region_msg *msg_param = (struct mp_region_msg *)msg.param;
116         struct mp_region_msg *reply_param;
117         struct memif_region *r;
118         struct pmd_process_private *proc_private = dev->process_private;
119
120         MIF_LOG(DEBUG, "Requesting memory regions");
121
122         for (i = 0; i < ETH_MEMIF_MAX_REGION_NUM; i++) {
123                 /* Prepare the message */
124                 memset(&msg, 0, sizeof(msg));
125                 strlcpy(msg.name, MEMIF_MP_SEND_REGION, sizeof(msg.name));
126                 strlcpy(msg_param->port_name, dev->data->name,
127                         sizeof(msg_param->port_name));
128                 msg_param->idx = i;
129                 msg.len_param = sizeof(*msg_param);
130
131                 /* Send message */
132                 ret = rte_mp_request_sync(&msg, &replies, &timeout);
133                 if (ret < 0 || replies.nb_received != 1) {
134                         MIF_LOG(ERR, "Failed to send mp msg: %d",
135                                 rte_errno);
136                         return -1;
137                 }
138
139                 reply = &replies.msgs[0];
140                 reply_param = (struct mp_region_msg *)reply->param;
141
142                 if (reply_param->size > 0) {
143                         r = rte_zmalloc("region", sizeof(struct memif_region), 0);
144                         if (r == NULL) {
145                                 MIF_LOG(ERR, "Failed to alloc memif region.");
146                                 free(reply);
147                                 return -ENOMEM;
148                         }
149                         r->region_size = reply_param->size;
150                         if (reply->num_fds < 1) {
151                                 MIF_LOG(ERR, "Missing file descriptor.");
152                                 free(reply);
153                                 return -1;
154                         }
155                         r->fd = reply->fds[0];
156                         r->addr = NULL;
157
158                         proc_private->regions[reply_param->idx] = r;
159                         proc_private->regions_num++;
160                 }
161                 free(reply);
162         }
163
164         return memif_connect(dev);
165 }
166
167 static int
168 memif_dev_info(struct rte_eth_dev *dev __rte_unused, struct rte_eth_dev_info *dev_info)
169 {
170         dev_info->max_mac_addrs = 1;
171         dev_info->max_rx_pktlen = (uint32_t)ETH_FRAME_LEN;
172         dev_info->max_rx_queues = ETH_MEMIF_MAX_NUM_Q_PAIRS;
173         dev_info->max_tx_queues = ETH_MEMIF_MAX_NUM_Q_PAIRS;
174         dev_info->min_rx_bufsize = 0;
175
176         return 0;
177 }
178
179 static memif_ring_t *
180 memif_get_ring(struct pmd_internals *pmd, struct pmd_process_private *proc_private,
181                memif_ring_type_t type, uint16_t ring_num)
182 {
183         /* rings only in region 0 */
184         void *p = proc_private->regions[0]->addr;
185         int ring_size = sizeof(memif_ring_t) + sizeof(memif_desc_t) *
186             (1 << pmd->run.log2_ring_size);
187
188         p = (uint8_t *)p + (ring_num + type * pmd->run.num_s2m_rings) * ring_size;
189
190         return (memif_ring_t *)p;
191 }
192
193 static memif_region_offset_t
194 memif_get_ring_offset(struct rte_eth_dev *dev, struct memif_queue *mq,
195                       memif_ring_type_t type, uint16_t num)
196 {
197         struct pmd_internals *pmd = dev->data->dev_private;
198         struct pmd_process_private *proc_private = dev->process_private;
199
200         return ((uint8_t *)memif_get_ring(pmd, proc_private, type, num) -
201                 (uint8_t *)proc_private->regions[mq->region]->addr);
202 }
203
204 static memif_ring_t *
205 memif_get_ring_from_queue(struct pmd_process_private *proc_private,
206                           struct memif_queue *mq)
207 {
208         struct memif_region *r;
209
210         r = proc_private->regions[mq->region];
211         if (r == NULL)
212                 return NULL;
213
214         return (memif_ring_t *)((uint8_t *)r->addr + mq->ring_offset);
215 }
216
217 static void *
218 memif_get_buffer(struct pmd_process_private *proc_private, memif_desc_t *d)
219 {
220         return ((uint8_t *)proc_private->regions[d->region]->addr + d->offset);
221 }
222
223 static int
224 memif_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *cur_tail,
225                     struct rte_mbuf *tail)
226 {
227         /* Check for number-of-segments-overflow */
228         if (unlikely(head->nb_segs + tail->nb_segs > RTE_MBUF_MAX_NB_SEGS))
229                 return -EOVERFLOW;
230
231         /* Chain 'tail' onto the old tail */
232         cur_tail->next = tail;
233
234         /* accumulate number of segments and total length. */
235         head->nb_segs = (uint16_t)(head->nb_segs + tail->nb_segs);
236
237         tail->pkt_len = tail->data_len;
238         head->pkt_len += tail->pkt_len;
239
240         return 0;
241 }
242
243 static uint16_t
244 eth_memif_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
245 {
246         struct memif_queue *mq = queue;
247         struct pmd_internals *pmd = rte_eth_devices[mq->in_port].data->dev_private;
248         struct pmd_process_private *proc_private =
249                 rte_eth_devices[mq->in_port].process_private;
250         memif_ring_t *ring = memif_get_ring_from_queue(proc_private, mq);
251         uint16_t cur_slot, last_slot, n_slots, ring_size, mask, s0;
252         uint16_t n_rx_pkts = 0;
253         uint16_t mbuf_size = rte_pktmbuf_data_room_size(mq->mempool) -
254                 RTE_PKTMBUF_HEADROOM;
255         uint16_t src_len, src_off, dst_len, dst_off, cp_len;
256         memif_ring_type_t type = mq->type;
257         memif_desc_t *d0;
258         struct rte_mbuf *mbuf, *mbuf_head, *mbuf_tail;
259         uint64_t b;
260         ssize_t size __rte_unused;
261         uint16_t head;
262         int ret;
263         struct rte_eth_link link;
264
265         if (unlikely((pmd->flags & ETH_MEMIF_FLAG_CONNECTED) == 0))
266                 return 0;
267         if (unlikely(ring == NULL)) {
268                 /* Secondary process will attempt to request regions. */
269                 ret = rte_eth_link_get(mq->in_port, &link);
270                 if (ret < 0)
271                         MIF_LOG(ERR, "Failed to get port %u link info: %s",
272                                 mq->in_port, rte_strerror(-ret));
273                 return 0;
274         }
275
276         /* consume interrupt */
277         if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0)
278                 size = read(mq->intr_handle.fd, &b, sizeof(b));
279
280         ring_size = 1 << mq->log2_ring_size;
281         mask = ring_size - 1;
282
283         if (type == MEMIF_RING_S2M) {
284                 cur_slot = mq->last_head;
285                 last_slot = __atomic_load_n(&ring->head, __ATOMIC_ACQUIRE);
286         } else {
287                 cur_slot = mq->last_tail;
288                 last_slot = __atomic_load_n(&ring->tail, __ATOMIC_ACQUIRE);
289         }
290
291         if (cur_slot == last_slot)
292                 goto refill;
293         n_slots = last_slot - cur_slot;
294
295         while (n_slots && n_rx_pkts < nb_pkts) {
296                 mbuf_head = rte_pktmbuf_alloc(mq->mempool);
297                 if (unlikely(mbuf_head == NULL))
298                         goto no_free_bufs;
299                 mbuf = mbuf_head;
300                 mbuf->port = mq->in_port;
301
302 next_slot:
303                 s0 = cur_slot & mask;
304                 d0 = &ring->desc[s0];
305
306                 src_len = d0->length;
307                 dst_off = 0;
308                 src_off = 0;
309
310                 do {
311                         dst_len = mbuf_size - dst_off;
312                         if (dst_len == 0) {
313                                 dst_off = 0;
314                                 dst_len = mbuf_size;
315
316                                 /* store pointer to tail */
317                                 mbuf_tail = mbuf;
318                                 mbuf = rte_pktmbuf_alloc(mq->mempool);
319                                 if (unlikely(mbuf == NULL))
320                                         goto no_free_bufs;
321                                 mbuf->port = mq->in_port;
322                                 ret = memif_pktmbuf_chain(mbuf_head, mbuf_tail, mbuf);
323                                 if (unlikely(ret < 0)) {
324                                         MIF_LOG(ERR, "number-of-segments-overflow");
325                                         rte_pktmbuf_free(mbuf);
326                                         goto no_free_bufs;
327                                 }
328                         }
329                         cp_len = RTE_MIN(dst_len, src_len);
330
331                         rte_pktmbuf_data_len(mbuf) += cp_len;
332                         rte_pktmbuf_pkt_len(mbuf) = rte_pktmbuf_data_len(mbuf);
333                         if (mbuf != mbuf_head)
334                                 rte_pktmbuf_pkt_len(mbuf_head) += cp_len;
335
336                         memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, dst_off),
337                                (uint8_t *)memif_get_buffer(proc_private, d0) +
338                                src_off, cp_len);
339
340                         src_off += cp_len;
341                         dst_off += cp_len;
342                         src_len -= cp_len;
343                 } while (src_len);
344
345                 cur_slot++;
346                 n_slots--;
347
348                 if (d0->flags & MEMIF_DESC_FLAG_NEXT)
349                         goto next_slot;
350
351                 mq->n_bytes += rte_pktmbuf_pkt_len(mbuf_head);
352                 *bufs++ = mbuf_head;
353                 n_rx_pkts++;
354         }
355
356 no_free_bufs:
357         if (type == MEMIF_RING_S2M) {
358                 __atomic_store_n(&ring->tail, cur_slot, __ATOMIC_RELEASE);
359                 mq->last_head = cur_slot;
360         } else {
361                 mq->last_tail = cur_slot;
362         }
363
364 refill:
365         if (type == MEMIF_RING_M2S) {
366                 head = __atomic_load_n(&ring->head, __ATOMIC_ACQUIRE);
367                 n_slots = ring_size - head + mq->last_tail;
368
369                 while (n_slots--) {
370                         s0 = head++ & mask;
371                         d0 = &ring->desc[s0];
372                         d0->length = pmd->run.pkt_buffer_size;
373                 }
374                 __atomic_store_n(&ring->head, head, __ATOMIC_RELEASE);
375         }
376
377         mq->n_pkts += n_rx_pkts;
378         return n_rx_pkts;
379 }
380
381 static uint16_t
382 eth_memif_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
383 {
384         struct memif_queue *mq = queue;
385         struct pmd_internals *pmd = rte_eth_devices[mq->in_port].data->dev_private;
386         struct pmd_process_private *proc_private =
387                 rte_eth_devices[mq->in_port].process_private;
388         memif_ring_t *ring = memif_get_ring_from_queue(proc_private, mq);
389         uint16_t slot, saved_slot, n_free, ring_size, mask, n_tx_pkts = 0;
390         uint16_t src_len, src_off, dst_len, dst_off, cp_len;
391         memif_ring_type_t type = mq->type;
392         memif_desc_t *d0;
393         struct rte_mbuf *mbuf;
394         struct rte_mbuf *mbuf_head;
395         uint64_t a;
396         ssize_t size;
397         struct rte_eth_link link;
398
399         if (unlikely((pmd->flags & ETH_MEMIF_FLAG_CONNECTED) == 0))
400                 return 0;
401         if (unlikely(ring == NULL)) {
402                 int ret;
403
404                 /* Secondary process will attempt to request regions. */
405                 ret = rte_eth_link_get(mq->in_port, &link);
406                 if (ret < 0)
407                         MIF_LOG(ERR, "Failed to get port %u link info: %s",
408                                 mq->in_port, rte_strerror(-ret));
409                 return 0;
410         }
411
412         ring_size = 1 << mq->log2_ring_size;
413         mask = ring_size - 1;
414
415         n_free = __atomic_load_n(&ring->tail, __ATOMIC_ACQUIRE) - mq->last_tail;
416         mq->last_tail += n_free;
417
418         if (type == MEMIF_RING_S2M) {
419                 slot = __atomic_load_n(&ring->head, __ATOMIC_ACQUIRE);
420                 n_free = ring_size - slot + mq->last_tail;
421         } else {
422                 slot = __atomic_load_n(&ring->tail, __ATOMIC_ACQUIRE);
423                 n_free = __atomic_load_n(&ring->head, __ATOMIC_ACQUIRE) - slot;
424         }
425
426         while (n_tx_pkts < nb_pkts && n_free) {
427                 mbuf_head = *bufs++;
428                 mbuf = mbuf_head;
429
430                 saved_slot = slot;
431                 d0 = &ring->desc[slot & mask];
432                 dst_off = 0;
433                 dst_len = (type == MEMIF_RING_S2M) ?
434                         pmd->run.pkt_buffer_size : d0->length;
435
436 next_in_chain:
437                 src_off = 0;
438                 src_len = rte_pktmbuf_data_len(mbuf);
439
440                 while (src_len) {
441                         if (dst_len == 0) {
442                                 if (n_free) {
443                                         slot++;
444                                         n_free--;
445                                         d0->flags |= MEMIF_DESC_FLAG_NEXT;
446                                         d0 = &ring->desc[slot & mask];
447                                         dst_off = 0;
448                                         dst_len = (type == MEMIF_RING_S2M) ?
449                                             pmd->run.pkt_buffer_size : d0->length;
450                                         d0->flags = 0;
451                                 } else {
452                                         slot = saved_slot;
453                                         goto no_free_slots;
454                                 }
455                         }
456                         cp_len = RTE_MIN(dst_len, src_len);
457
458                         memcpy((uint8_t *)memif_get_buffer(proc_private, d0) + dst_off,
459                                rte_pktmbuf_mtod_offset(mbuf, void *, src_off),
460                                cp_len);
461
462                         mq->n_bytes += cp_len;
463                         src_off += cp_len;
464                         dst_off += cp_len;
465                         src_len -= cp_len;
466                         dst_len -= cp_len;
467
468                         d0->length = dst_off;
469                 }
470
471                 if (rte_pktmbuf_is_contiguous(mbuf) == 0) {
472                         mbuf = mbuf->next;
473                         goto next_in_chain;
474                 }
475
476                 n_tx_pkts++;
477                 slot++;
478                 n_free--;
479                 rte_pktmbuf_free(mbuf_head);
480         }
481
482 no_free_slots:
483         if (type == MEMIF_RING_S2M)
484                 __atomic_store_n(&ring->head, slot, __ATOMIC_RELEASE);
485         else
486                 __atomic_store_n(&ring->tail, slot, __ATOMIC_RELEASE);
487
488         if ((ring->flags & MEMIF_RING_FLAG_MASK_INT) == 0) {
489                 a = 1;
490                 size = write(mq->intr_handle.fd, &a, sizeof(a));
491                 if (unlikely(size < 0)) {
492                         MIF_LOG(WARNING,
493                                 "Failed to send interrupt. %s", strerror(errno));
494                 }
495         }
496
497         mq->n_pkts += n_tx_pkts;
498         return n_tx_pkts;
499 }
500
501 void
502 memif_free_regions(struct pmd_process_private *proc_private)
503 {
504         int i;
505         struct memif_region *r;
506
507         MIF_LOG(DEBUG, "Free memory regions");
508         /* regions are allocated contiguously, so it's
509          * enough to loop until 'proc_private->regions_num'
510          */
511         for (i = 0; i < proc_private->regions_num; i++) {
512                 r = proc_private->regions[i];
513                 if (r != NULL) {
514                         if (r->addr != NULL) {
515                                 munmap(r->addr, r->region_size);
516                                 if (r->fd > 0) {
517                                         close(r->fd);
518                                         r->fd = -1;
519                                 }
520                         }
521                         rte_free(r);
522                         proc_private->regions[i] = NULL;
523                 }
524         }
525         proc_private->regions_num = 0;
526 }
527
528 static int
529 memif_region_init_shm(struct rte_eth_dev *dev, uint8_t has_buffers)
530 {
531         struct pmd_internals *pmd = dev->data->dev_private;
532         struct pmd_process_private *proc_private = dev->process_private;
533         char shm_name[ETH_MEMIF_SHM_NAME_SIZE];
534         int ret = 0;
535         struct memif_region *r;
536
537         if (proc_private->regions_num >= ETH_MEMIF_MAX_REGION_NUM) {
538                 MIF_LOG(ERR, "Too many regions.");
539                 return -1;
540         }
541
542         r = rte_zmalloc("region", sizeof(struct memif_region), 0);
543         if (r == NULL) {
544                 MIF_LOG(ERR, "Failed to alloc memif region.");
545                 return -ENOMEM;
546         }
547
548         /* calculate buffer offset */
549         r->pkt_buffer_offset = (pmd->run.num_s2m_rings + pmd->run.num_m2s_rings) *
550             (sizeof(memif_ring_t) + sizeof(memif_desc_t) *
551             (1 << pmd->run.log2_ring_size));
552
553         r->region_size = r->pkt_buffer_offset;
554         /* if region has buffers, add buffers size to region_size */
555         if (has_buffers == 1)
556                 r->region_size += (uint32_t)(pmd->run.pkt_buffer_size *
557                         (1 << pmd->run.log2_ring_size) *
558                         (pmd->run.num_s2m_rings +
559                          pmd->run.num_m2s_rings));
560
561         memset(shm_name, 0, sizeof(char) * ETH_MEMIF_SHM_NAME_SIZE);
562         snprintf(shm_name, ETH_MEMIF_SHM_NAME_SIZE, "memif_region_%d",
563                  proc_private->regions_num);
564
565         r->fd = memfd_create(shm_name, MFD_ALLOW_SEALING);
566         if (r->fd < 0) {
567                 MIF_LOG(ERR, "Failed to create shm file: %s.", strerror(errno));
568                 ret = -1;
569                 goto error;
570         }
571
572         ret = fcntl(r->fd, F_ADD_SEALS, F_SEAL_SHRINK);
573         if (ret < 0) {
574                 MIF_LOG(ERR, "Failed to add seals to shm file: %s.", strerror(errno));
575                 goto error;
576         }
577
578         ret = ftruncate(r->fd, r->region_size);
579         if (ret < 0) {
580                 MIF_LOG(ERR, "Failed to truncate shm file: %s.", strerror(errno));
581                 goto error;
582         }
583
584         r->addr = mmap(NULL, r->region_size, PROT_READ |
585                        PROT_WRITE, MAP_SHARED, r->fd, 0);
586         if (r->addr == MAP_FAILED) {
587                 MIF_LOG(ERR, "Failed to mmap shm region: %s.", strerror(ret));
588                 ret = -1;
589                 goto error;
590         }
591
592         proc_private->regions[proc_private->regions_num] = r;
593         proc_private->regions_num++;
594
595         return ret;
596
597 error:
598         if (r->fd > 0)
599                 close(r->fd);
600         r->fd = -1;
601
602         return ret;
603 }
604
605 static int
606 memif_regions_init(struct rte_eth_dev *dev)
607 {
608         int ret;
609
610         /* create one buffer region */
611         ret = memif_region_init_shm(dev, /* has buffer */ 1);
612         if (ret < 0)
613                 return ret;
614
615         return 0;
616 }
617
618 static void
619 memif_init_rings(struct rte_eth_dev *dev)
620 {
621         struct pmd_internals *pmd = dev->data->dev_private;
622         struct pmd_process_private *proc_private = dev->process_private;
623         memif_ring_t *ring;
624         int i, j;
625         uint16_t slot;
626
627         for (i = 0; i < pmd->run.num_s2m_rings; i++) {
628                 ring = memif_get_ring(pmd, proc_private, MEMIF_RING_S2M, i);
629                 __atomic_store_n(&ring->head, 0, __ATOMIC_RELAXED);
630                 __atomic_store_n(&ring->tail, 0, __ATOMIC_RELAXED);
631                 ring->cookie = MEMIF_COOKIE;
632                 ring->flags = 0;
633                 for (j = 0; j < (1 << pmd->run.log2_ring_size); j++) {
634                         slot = i * (1 << pmd->run.log2_ring_size) + j;
635                         ring->desc[j].region = 0;
636                         ring->desc[j].offset =
637                                 proc_private->regions[0]->pkt_buffer_offset +
638                                 (uint32_t)(slot * pmd->run.pkt_buffer_size);
639                         ring->desc[j].length = pmd->run.pkt_buffer_size;
640                 }
641         }
642
643         for (i = 0; i < pmd->run.num_m2s_rings; i++) {
644                 ring = memif_get_ring(pmd, proc_private, MEMIF_RING_M2S, i);
645                 __atomic_store_n(&ring->head, 0, __ATOMIC_RELAXED);
646                 __atomic_store_n(&ring->tail, 0, __ATOMIC_RELAXED);
647                 ring->cookie = MEMIF_COOKIE;
648                 ring->flags = 0;
649                 for (j = 0; j < (1 << pmd->run.log2_ring_size); j++) {
650                         slot = (i + pmd->run.num_s2m_rings) *
651                             (1 << pmd->run.log2_ring_size) + j;
652                         ring->desc[j].region = 0;
653                         ring->desc[j].offset =
654                                 proc_private->regions[0]->pkt_buffer_offset +
655                                 (uint32_t)(slot * pmd->run.pkt_buffer_size);
656                         ring->desc[j].length = pmd->run.pkt_buffer_size;
657                 }
658         }
659 }
660
661 /* called only by slave */
662 static void
663 memif_init_queues(struct rte_eth_dev *dev)
664 {
665         struct pmd_internals *pmd = dev->data->dev_private;
666         struct memif_queue *mq;
667         int i;
668
669         for (i = 0; i < pmd->run.num_s2m_rings; i++) {
670                 mq = dev->data->tx_queues[i];
671                 mq->log2_ring_size = pmd->run.log2_ring_size;
672                 /* queues located only in region 0 */
673                 mq->region = 0;
674                 mq->ring_offset = memif_get_ring_offset(dev, mq, MEMIF_RING_S2M, i);
675                 mq->last_head = 0;
676                 mq->last_tail = 0;
677                 mq->intr_handle.fd = eventfd(0, EFD_NONBLOCK);
678                 if (mq->intr_handle.fd < 0) {
679                         MIF_LOG(WARNING,
680                                 "Failed to create eventfd for tx queue %d: %s.", i,
681                                 strerror(errno));
682                 }
683         }
684
685         for (i = 0; i < pmd->run.num_m2s_rings; i++) {
686                 mq = dev->data->rx_queues[i];
687                 mq->log2_ring_size = pmd->run.log2_ring_size;
688                 /* queues located only in region 0 */
689                 mq->region = 0;
690                 mq->ring_offset = memif_get_ring_offset(dev, mq, MEMIF_RING_M2S, i);
691                 mq->last_head = 0;
692                 mq->last_tail = 0;
693                 mq->intr_handle.fd = eventfd(0, EFD_NONBLOCK);
694                 if (mq->intr_handle.fd < 0) {
695                         MIF_LOG(WARNING,
696                                 "Failed to create eventfd for rx queue %d: %s.", i,
697                                 strerror(errno));
698                 }
699         }
700 }
701
702 int
703 memif_init_regions_and_queues(struct rte_eth_dev *dev)
704 {
705         int ret;
706
707         ret = memif_regions_init(dev);
708         if (ret < 0)
709                 return ret;
710
711         memif_init_rings(dev);
712
713         memif_init_queues(dev);
714
715         return 0;
716 }
717
718 int
719 memif_connect(struct rte_eth_dev *dev)
720 {
721         struct pmd_internals *pmd = dev->data->dev_private;
722         struct pmd_process_private *proc_private = dev->process_private;
723         struct memif_region *mr;
724         struct memif_queue *mq;
725         memif_ring_t *ring;
726         int i;
727
728         for (i = 0; i < proc_private->regions_num; i++) {
729                 mr = proc_private->regions[i];
730                 if (mr != NULL) {
731                         if (mr->addr == NULL) {
732                                 if (mr->fd < 0)
733                                         return -1;
734                                 mr->addr = mmap(NULL, mr->region_size,
735                                                 PROT_READ | PROT_WRITE,
736                                                 MAP_SHARED, mr->fd, 0);
737                                 if (mr->addr == NULL)
738                                         return -1;
739                         }
740                 }
741         }
742
743         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
744                 for (i = 0; i < pmd->run.num_s2m_rings; i++) {
745                         mq = (pmd->role == MEMIF_ROLE_SLAVE) ?
746                             dev->data->tx_queues[i] : dev->data->rx_queues[i];
747                         ring = memif_get_ring_from_queue(proc_private, mq);
748                         if (ring == NULL || ring->cookie != MEMIF_COOKIE) {
749                                 MIF_LOG(ERR, "Wrong ring");
750                                 return -1;
751                         }
752                         __atomic_store_n(&ring->head, 0, __ATOMIC_RELAXED);
753                         __atomic_store_n(&ring->tail, 0, __ATOMIC_RELAXED);
754                         mq->last_head = 0;
755                         mq->last_tail = 0;
756                         /* enable polling mode */
757                         if (pmd->role == MEMIF_ROLE_MASTER)
758                                 ring->flags = MEMIF_RING_FLAG_MASK_INT;
759                 }
760                 for (i = 0; i < pmd->run.num_m2s_rings; i++) {
761                         mq = (pmd->role == MEMIF_ROLE_SLAVE) ?
762                             dev->data->rx_queues[i] : dev->data->tx_queues[i];
763                         ring = memif_get_ring_from_queue(proc_private, mq);
764                         if (ring == NULL || ring->cookie != MEMIF_COOKIE) {
765                                 MIF_LOG(ERR, "Wrong ring");
766                                 return -1;
767                         }
768                         __atomic_store_n(&ring->head, 0, __ATOMIC_RELAXED);
769                         __atomic_store_n(&ring->tail, 0, __ATOMIC_RELAXED);
770                         mq->last_head = 0;
771                         mq->last_tail = 0;
772                         /* enable polling mode */
773                         if (pmd->role == MEMIF_ROLE_SLAVE)
774                                 ring->flags = MEMIF_RING_FLAG_MASK_INT;
775                 }
776
777                 pmd->flags &= ~ETH_MEMIF_FLAG_CONNECTING;
778                 pmd->flags |= ETH_MEMIF_FLAG_CONNECTED;
779                 dev->data->dev_link.link_status = ETH_LINK_UP;
780         }
781         MIF_LOG(INFO, "Connected.");
782         return 0;
783 }
784
785 static int
786 memif_dev_start(struct rte_eth_dev *dev)
787 {
788         struct pmd_internals *pmd = dev->data->dev_private;
789         int ret = 0;
790
791         switch (pmd->role) {
792         case MEMIF_ROLE_SLAVE:
793                 ret = memif_connect_slave(dev);
794                 break;
795         case MEMIF_ROLE_MASTER:
796                 ret = memif_connect_master(dev);
797                 break;
798         default:
799                 MIF_LOG(ERR, "%s: Unknown role: %d.",
800                         rte_vdev_device_name(pmd->vdev), pmd->role);
801                 ret = -1;
802                 break;
803         }
804
805         return ret;
806 }
807
808 static void
809 memif_dev_close(struct rte_eth_dev *dev)
810 {
811         struct pmd_internals *pmd = dev->data->dev_private;
812         int i;
813
814         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
815                 memif_msg_enq_disconnect(pmd->cc, "Device closed", 0);
816                 memif_disconnect(dev);
817
818                 for (i = 0; i < dev->data->nb_rx_queues; i++)
819                         (*dev->dev_ops->rx_queue_release)(dev->data->rx_queues[i]);
820                 for (i = 0; i < dev->data->nb_tx_queues; i++)
821                         (*dev->dev_ops->tx_queue_release)(dev->data->tx_queues[i]);
822
823                 memif_socket_remove_device(dev);
824         } else {
825                 memif_disconnect(dev);
826         }
827
828         rte_free(dev->process_private);
829 }
830
831 static int
832 memif_dev_configure(struct rte_eth_dev *dev)
833 {
834         struct pmd_internals *pmd = dev->data->dev_private;
835
836         /*
837          * SLAVE - TXQ
838          * MASTER - RXQ
839          */
840         pmd->cfg.num_s2m_rings = (pmd->role == MEMIF_ROLE_SLAVE) ?
841                                   dev->data->nb_tx_queues : dev->data->nb_rx_queues;
842
843         /*
844          * SLAVE - RXQ
845          * MASTER - TXQ
846          */
847         pmd->cfg.num_m2s_rings = (pmd->role == MEMIF_ROLE_SLAVE) ?
848                                   dev->data->nb_rx_queues : dev->data->nb_tx_queues;
849
850         return 0;
851 }
852
853 static int
854 memif_tx_queue_setup(struct rte_eth_dev *dev,
855                      uint16_t qid,
856                      uint16_t nb_tx_desc __rte_unused,
857                      unsigned int socket_id __rte_unused,
858                      const struct rte_eth_txconf *tx_conf __rte_unused)
859 {
860         struct pmd_internals *pmd = dev->data->dev_private;
861         struct memif_queue *mq;
862
863         mq = rte_zmalloc("tx-queue", sizeof(struct memif_queue), 0);
864         if (mq == NULL) {
865                 MIF_LOG(ERR, "%s: Failed to allocate tx queue id: %u",
866                         rte_vdev_device_name(pmd->vdev), qid);
867                 return -ENOMEM;
868         }
869
870         mq->type =
871             (pmd->role == MEMIF_ROLE_SLAVE) ? MEMIF_RING_S2M : MEMIF_RING_M2S;
872         mq->n_pkts = 0;
873         mq->n_bytes = 0;
874         mq->intr_handle.fd = -1;
875         mq->intr_handle.type = RTE_INTR_HANDLE_EXT;
876         dev->data->tx_queues[qid] = mq;
877
878         return 0;
879 }
880
881 static int
882 memif_rx_queue_setup(struct rte_eth_dev *dev,
883                      uint16_t qid,
884                      uint16_t nb_rx_desc __rte_unused,
885                      unsigned int socket_id __rte_unused,
886                      const struct rte_eth_rxconf *rx_conf __rte_unused,
887                      struct rte_mempool *mb_pool)
888 {
889         struct pmd_internals *pmd = dev->data->dev_private;
890         struct memif_queue *mq;
891
892         mq = rte_zmalloc("rx-queue", sizeof(struct memif_queue), 0);
893         if (mq == NULL) {
894                 MIF_LOG(ERR, "%s: Failed to allocate rx queue id: %u",
895                         rte_vdev_device_name(pmd->vdev), qid);
896                 return -ENOMEM;
897         }
898
899         mq->type = (pmd->role == MEMIF_ROLE_SLAVE) ? MEMIF_RING_M2S : MEMIF_RING_S2M;
900         mq->n_pkts = 0;
901         mq->n_bytes = 0;
902         mq->intr_handle.fd = -1;
903         mq->intr_handle.type = RTE_INTR_HANDLE_EXT;
904         mq->mempool = mb_pool;
905         mq->in_port = dev->data->port_id;
906         dev->data->rx_queues[qid] = mq;
907
908         return 0;
909 }
910
911 static void
912 memif_queue_release(void *queue)
913 {
914         struct memif_queue *mq = (struct memif_queue *)queue;
915
916         if (!mq)
917                 return;
918
919         rte_free(mq);
920 }
921
922 static int
923 memif_link_update(struct rte_eth_dev *dev,
924                   int wait_to_complete __rte_unused)
925 {
926         struct pmd_process_private *proc_private;
927
928         if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
929                 proc_private = dev->process_private;
930                 if (dev->data->dev_link.link_status == ETH_LINK_UP &&
931                                 proc_private->regions_num == 0) {
932                         memif_mp_request_regions(dev);
933                 } else if (dev->data->dev_link.link_status == ETH_LINK_DOWN &&
934                                 proc_private->regions_num > 0) {
935                         memif_free_regions(proc_private);
936                 }
937         }
938         return 0;
939 }
940
941 static int
942 memif_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
943 {
944         struct pmd_internals *pmd = dev->data->dev_private;
945         struct memif_queue *mq;
946         int i;
947         uint8_t tmp, nq;
948
949         stats->ipackets = 0;
950         stats->ibytes = 0;
951         stats->opackets = 0;
952         stats->obytes = 0;
953
954         tmp = (pmd->role == MEMIF_ROLE_SLAVE) ? pmd->run.num_s2m_rings :
955             pmd->run.num_m2s_rings;
956         nq = (tmp < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? tmp :
957             RTE_ETHDEV_QUEUE_STAT_CNTRS;
958
959         /* RX stats */
960         for (i = 0; i < nq; i++) {
961                 mq = dev->data->rx_queues[i];
962                 stats->q_ipackets[i] = mq->n_pkts;
963                 stats->q_ibytes[i] = mq->n_bytes;
964                 stats->ipackets += mq->n_pkts;
965                 stats->ibytes += mq->n_bytes;
966         }
967
968         tmp = (pmd->role == MEMIF_ROLE_SLAVE) ? pmd->run.num_m2s_rings :
969             pmd->run.num_s2m_rings;
970         nq = (tmp < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? tmp :
971             RTE_ETHDEV_QUEUE_STAT_CNTRS;
972
973         /* TX stats */
974         for (i = 0; i < nq; i++) {
975                 mq = dev->data->tx_queues[i];
976                 stats->q_opackets[i] = mq->n_pkts;
977                 stats->q_obytes[i] = mq->n_bytes;
978                 stats->opackets += mq->n_pkts;
979                 stats->obytes += mq->n_bytes;
980         }
981         return 0;
982 }
983
984 static int
985 memif_stats_reset(struct rte_eth_dev *dev)
986 {
987         struct pmd_internals *pmd = dev->data->dev_private;
988         int i;
989         struct memif_queue *mq;
990
991         for (i = 0; i < pmd->run.num_s2m_rings; i++) {
992                 mq = (pmd->role == MEMIF_ROLE_SLAVE) ? dev->data->tx_queues[i] :
993                     dev->data->rx_queues[i];
994                 mq->n_pkts = 0;
995                 mq->n_bytes = 0;
996         }
997         for (i = 0; i < pmd->run.num_m2s_rings; i++) {
998                 mq = (pmd->role == MEMIF_ROLE_SLAVE) ? dev->data->rx_queues[i] :
999                     dev->data->tx_queues[i];
1000                 mq->n_pkts = 0;
1001                 mq->n_bytes = 0;
1002         }
1003
1004         return 0;
1005 }
1006
1007 static int
1008 memif_rx_queue_intr_enable(struct rte_eth_dev *dev __rte_unused,
1009                            uint16_t qid __rte_unused)
1010 {
1011         MIF_LOG(WARNING, "Interrupt mode not supported.");
1012
1013         return -1;
1014 }
1015
1016 static int
1017 memif_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t qid __rte_unused)
1018 {
1019         struct pmd_internals *pmd __rte_unused = dev->data->dev_private;
1020
1021         return 0;
1022 }
1023
1024 static const struct eth_dev_ops ops = {
1025         .dev_start = memif_dev_start,
1026         .dev_close = memif_dev_close,
1027         .dev_infos_get = memif_dev_info,
1028         .dev_configure = memif_dev_configure,
1029         .tx_queue_setup = memif_tx_queue_setup,
1030         .rx_queue_setup = memif_rx_queue_setup,
1031         .rx_queue_release = memif_queue_release,
1032         .tx_queue_release = memif_queue_release,
1033         .rx_queue_intr_enable = memif_rx_queue_intr_enable,
1034         .rx_queue_intr_disable = memif_rx_queue_intr_disable,
1035         .link_update = memif_link_update,
1036         .stats_get = memif_stats_get,
1037         .stats_reset = memif_stats_reset,
1038 };
1039
1040 static int
1041 memif_create(struct rte_vdev_device *vdev, enum memif_role_t role,
1042              memif_interface_id_t id, uint32_t flags,
1043              const char *socket_filename,
1044              memif_log2_ring_size_t log2_ring_size,
1045              uint16_t pkt_buffer_size, const char *secret,
1046              struct rte_ether_addr *ether_addr)
1047 {
1048         int ret = 0;
1049         struct rte_eth_dev *eth_dev;
1050         struct rte_eth_dev_data *data;
1051         struct pmd_internals *pmd;
1052         struct pmd_process_private *process_private;
1053         const unsigned int numa_node = vdev->device.numa_node;
1054         const char *name = rte_vdev_device_name(vdev);
1055
1056         if (flags & ETH_MEMIF_FLAG_ZERO_COPY) {
1057                 MIF_LOG(ERR, "Zero-copy slave not supported.");
1058                 return -1;
1059         }
1060
1061         eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*pmd));
1062         if (eth_dev == NULL) {
1063                 MIF_LOG(ERR, "%s: Unable to allocate device struct.", name);
1064                 return -1;
1065         }
1066
1067         process_private = (struct pmd_process_private *)
1068                 rte_zmalloc(name, sizeof(struct pmd_process_private),
1069                             RTE_CACHE_LINE_SIZE);
1070
1071         if (process_private == NULL) {
1072                 MIF_LOG(ERR, "Failed to alloc memory for process private");
1073                 return -1;
1074         }
1075         eth_dev->process_private = process_private;
1076
1077         pmd = eth_dev->data->dev_private;
1078         memset(pmd, 0, sizeof(*pmd));
1079
1080         pmd->id = id;
1081         pmd->flags = flags;
1082         pmd->flags |= ETH_MEMIF_FLAG_DISABLED;
1083         pmd->role = role;
1084
1085         ret = memif_socket_init(eth_dev, socket_filename);
1086         if (ret < 0)
1087                 return ret;
1088
1089         memset(pmd->secret, 0, sizeof(char) * ETH_MEMIF_SECRET_SIZE);
1090         if (secret != NULL)
1091                 strlcpy(pmd->secret, secret, sizeof(pmd->secret));
1092
1093         pmd->cfg.log2_ring_size = log2_ring_size;
1094         /* set in .dev_configure() */
1095         pmd->cfg.num_s2m_rings = 0;
1096         pmd->cfg.num_m2s_rings = 0;
1097
1098         pmd->cfg.pkt_buffer_size = pkt_buffer_size;
1099
1100         data = eth_dev->data;
1101         data->dev_private = pmd;
1102         data->numa_node = numa_node;
1103         data->mac_addrs = ether_addr;
1104
1105         eth_dev->dev_ops = &ops;
1106         eth_dev->device = &vdev->device;
1107         eth_dev->rx_pkt_burst = eth_memif_rx;
1108         eth_dev->tx_pkt_burst = eth_memif_tx;
1109
1110         eth_dev->data->dev_flags &= RTE_ETH_DEV_CLOSE_REMOVE;
1111
1112         rte_eth_dev_probing_finish(eth_dev);
1113
1114         return 0;
1115 }
1116
1117 static int
1118 memif_set_role(const char *key __rte_unused, const char *value,
1119                void *extra_args)
1120 {
1121         enum memif_role_t *role = (enum memif_role_t *)extra_args;
1122
1123         if (strstr(value, "master") != NULL) {
1124                 *role = MEMIF_ROLE_MASTER;
1125         } else if (strstr(value, "slave") != NULL) {
1126                 *role = MEMIF_ROLE_SLAVE;
1127         } else {
1128                 MIF_LOG(ERR, "Unknown role: %s.", value);
1129                 return -EINVAL;
1130         }
1131         return 0;
1132 }
1133
1134 static int
1135 memif_set_zc(const char *key __rte_unused, const char *value, void *extra_args)
1136 {
1137         uint32_t *flags = (uint32_t *)extra_args;
1138
1139         if (strstr(value, "yes") != NULL) {
1140                 *flags |= ETH_MEMIF_FLAG_ZERO_COPY;
1141         } else if (strstr(value, "no") != NULL) {
1142                 *flags &= ~ETH_MEMIF_FLAG_ZERO_COPY;
1143         } else {
1144                 MIF_LOG(ERR, "Failed to parse zero-copy param: %s.", value);
1145                 return -EINVAL;
1146         }
1147         return 0;
1148 }
1149
1150 static int
1151 memif_set_id(const char *key __rte_unused, const char *value, void *extra_args)
1152 {
1153         memif_interface_id_t *id = (memif_interface_id_t *)extra_args;
1154
1155         /* even if parsing fails, 0 is a valid id */
1156         *id = strtoul(value, NULL, 10);
1157         return 0;
1158 }
1159
1160 static int
1161 memif_set_bs(const char *key __rte_unused, const char *value, void *extra_args)
1162 {
1163         unsigned long tmp;
1164         uint16_t *pkt_buffer_size = (uint16_t *)extra_args;
1165
1166         tmp = strtoul(value, NULL, 10);
1167         if (tmp == 0 || tmp > 0xFFFF) {
1168                 MIF_LOG(ERR, "Invalid buffer size: %s.", value);
1169                 return -EINVAL;
1170         }
1171         *pkt_buffer_size = tmp;
1172         return 0;
1173 }
1174
1175 static int
1176 memif_set_rs(const char *key __rte_unused, const char *value, void *extra_args)
1177 {
1178         unsigned long tmp;
1179         memif_log2_ring_size_t *log2_ring_size =
1180             (memif_log2_ring_size_t *)extra_args;
1181
1182         tmp = strtoul(value, NULL, 10);
1183         if (tmp == 0 || tmp > ETH_MEMIF_MAX_LOG2_RING_SIZE) {
1184                 MIF_LOG(ERR, "Invalid ring size: %s (max %u).",
1185                         value, ETH_MEMIF_MAX_LOG2_RING_SIZE);
1186                 return -EINVAL;
1187         }
1188         *log2_ring_size = tmp;
1189         return 0;
1190 }
1191
1192 /* check if directory exists and if we have permission to read/write */
1193 static int
1194 memif_check_socket_filename(const char *filename)
1195 {
1196         char *dir = NULL, *tmp;
1197         uint32_t idx;
1198         int ret = 0;
1199
1200         tmp = strrchr(filename, '/');
1201         if (tmp != NULL) {
1202                 idx = tmp - filename;
1203                 dir = rte_zmalloc("memif_tmp", sizeof(char) * (idx + 1), 0);
1204                 if (dir == NULL) {
1205                         MIF_LOG(ERR, "Failed to allocate memory.");
1206                         return -1;
1207                 }
1208                 strlcpy(dir, filename, sizeof(char) * (idx + 1));
1209         }
1210
1211         if (dir == NULL || (faccessat(-1, dir, F_OK | R_OK |
1212                                         W_OK, AT_EACCESS) < 0)) {
1213                 MIF_LOG(ERR, "Invalid socket directory.");
1214                 ret = -EINVAL;
1215         }
1216
1217         if (dir != NULL)
1218                 rte_free(dir);
1219
1220         return ret;
1221 }
1222
1223 static int
1224 memif_set_socket_filename(const char *key __rte_unused, const char *value,
1225                           void *extra_args)
1226 {
1227         const char **socket_filename = (const char **)extra_args;
1228
1229         *socket_filename = value;
1230         return memif_check_socket_filename(*socket_filename);
1231 }
1232
1233 static int
1234 memif_set_mac(const char *key __rte_unused, const char *value, void *extra_args)
1235 {
1236         struct rte_ether_addr *ether_addr = (struct rte_ether_addr *)extra_args;
1237
1238         if (rte_ether_unformat_addr(value, ether_addr) < 0)
1239                 MIF_LOG(WARNING, "Failed to parse mac '%s'.", value);
1240         return 0;
1241 }
1242
1243 static int
1244 memif_set_secret(const char *key __rte_unused, const char *value, void *extra_args)
1245 {
1246         const char **secret = (const char **)extra_args;
1247
1248         *secret = value;
1249         return 0;
1250 }
1251
1252 static int
1253 rte_pmd_memif_probe(struct rte_vdev_device *vdev)
1254 {
1255         RTE_BUILD_BUG_ON(sizeof(memif_msg_t) != 128);
1256         RTE_BUILD_BUG_ON(sizeof(memif_desc_t) != 16);
1257         int ret = 0;
1258         struct rte_kvargs *kvlist;
1259         const char *name = rte_vdev_device_name(vdev);
1260         enum memif_role_t role = MEMIF_ROLE_SLAVE;
1261         memif_interface_id_t id = 0;
1262         uint16_t pkt_buffer_size = ETH_MEMIF_DEFAULT_PKT_BUFFER_SIZE;
1263         memif_log2_ring_size_t log2_ring_size = ETH_MEMIF_DEFAULT_RING_SIZE;
1264         const char *socket_filename = ETH_MEMIF_DEFAULT_SOCKET_FILENAME;
1265         uint32_t flags = 0;
1266         const char *secret = NULL;
1267         struct rte_ether_addr *ether_addr = rte_zmalloc("",
1268                 sizeof(struct rte_ether_addr), 0);
1269         struct rte_eth_dev *eth_dev;
1270
1271         rte_eth_random_addr(ether_addr->addr_bytes);
1272
1273         MIF_LOG(INFO, "Initialize MEMIF: %s.", name);
1274
1275         if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
1276                 eth_dev = rte_eth_dev_attach_secondary(name);
1277                 if (!eth_dev) {
1278                         MIF_LOG(ERR, "Failed to probe %s", name);
1279                         return -1;
1280                 }
1281
1282                 eth_dev->dev_ops = &ops;
1283                 eth_dev->device = &vdev->device;
1284                 eth_dev->rx_pkt_burst = eth_memif_rx;
1285                 eth_dev->tx_pkt_burst = eth_memif_tx;
1286
1287                 if (!rte_eal_primary_proc_alive(NULL)) {
1288                         MIF_LOG(ERR, "Primary process is missing");
1289                         return -1;
1290                 }
1291
1292                 eth_dev->process_private = (struct pmd_process_private *)
1293                         rte_zmalloc(name,
1294                                 sizeof(struct pmd_process_private),
1295                                 RTE_CACHE_LINE_SIZE);
1296                 if (eth_dev->process_private == NULL) {
1297                         MIF_LOG(ERR,
1298                                 "Failed to alloc memory for process private");
1299                         return -1;
1300                 }
1301
1302                 rte_eth_dev_probing_finish(eth_dev);
1303
1304                 return 0;
1305         }
1306
1307         ret = rte_mp_action_register(MEMIF_MP_SEND_REGION, memif_mp_send_region);
1308         /*
1309          * Primary process can continue probing, but secondary process won't
1310          * be able to get memory regions information
1311          */
1312         if (ret < 0 && rte_errno != EEXIST)
1313                 MIF_LOG(WARNING, "Failed to register mp action callback: %s",
1314                         strerror(rte_errno));
1315
1316         kvlist = rte_kvargs_parse(rte_vdev_device_args(vdev), valid_arguments);
1317
1318         /* parse parameters */
1319         if (kvlist != NULL) {
1320                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_ROLE_ARG,
1321                                          &memif_set_role, &role);
1322                 if (ret < 0)
1323                         goto exit;
1324                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_ID_ARG,
1325                                          &memif_set_id, &id);
1326                 if (ret < 0)
1327                         goto exit;
1328                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_PKT_BUFFER_SIZE_ARG,
1329                                          &memif_set_bs, &pkt_buffer_size);
1330                 if (ret < 0)
1331                         goto exit;
1332                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_RING_SIZE_ARG,
1333                                          &memif_set_rs, &log2_ring_size);
1334                 if (ret < 0)
1335                         goto exit;
1336                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_SOCKET_ARG,
1337                                          &memif_set_socket_filename,
1338                                          (void *)(&socket_filename));
1339                 if (ret < 0)
1340                         goto exit;
1341                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_MAC_ARG,
1342                                          &memif_set_mac, ether_addr);
1343                 if (ret < 0)
1344                         goto exit;
1345                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_ZC_ARG,
1346                                          &memif_set_zc, &flags);
1347                 if (ret < 0)
1348                         goto exit;
1349                 ret = rte_kvargs_process(kvlist, ETH_MEMIF_SECRET_ARG,
1350                                          &memif_set_secret, (void *)(&secret));
1351                 if (ret < 0)
1352                         goto exit;
1353         }
1354
1355         /* create interface */
1356         ret = memif_create(vdev, role, id, flags, socket_filename,
1357                            log2_ring_size, pkt_buffer_size, secret, ether_addr);
1358
1359 exit:
1360         if (kvlist != NULL)
1361                 rte_kvargs_free(kvlist);
1362         return ret;
1363 }
1364
1365 static int
1366 rte_pmd_memif_remove(struct rte_vdev_device *vdev)
1367 {
1368         struct rte_eth_dev *eth_dev;
1369
1370         eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(vdev));
1371         if (eth_dev == NULL)
1372                 return 0;
1373
1374         rte_eth_dev_close(eth_dev->data->port_id);
1375
1376         return 0;
1377 }
1378
1379 static struct rte_vdev_driver pmd_memif_drv = {
1380         .probe = rte_pmd_memif_probe,
1381         .remove = rte_pmd_memif_remove,
1382 };
1383
1384 RTE_PMD_REGISTER_VDEV(net_memif, pmd_memif_drv);
1385
1386 RTE_PMD_REGISTER_PARAM_STRING(net_memif,
1387                               ETH_MEMIF_ID_ARG "=<int>"
1388                               ETH_MEMIF_ROLE_ARG "=master|slave"
1389                               ETH_MEMIF_PKT_BUFFER_SIZE_ARG "=<int>"
1390                               ETH_MEMIF_RING_SIZE_ARG "=<int>"
1391                               ETH_MEMIF_SOCKET_ARG "=<string>"
1392                               ETH_MEMIF_MAC_ARG "=xx:xx:xx:xx:xx:xx"
1393                               ETH_MEMIF_ZC_ARG "=yes|no"
1394                               ETH_MEMIF_SECRET_ARG "=<string>");
1395
1396 int memif_logtype;
1397
1398 RTE_INIT(memif_init_log)
1399 {
1400         memif_logtype = rte_log_register("pmd.net.memif");
1401         if (memif_logtype >= 0)
1402                 rte_log_set_level(memif_logtype, RTE_LOG_NOTICE);
1403 }