119af5a38SHeinrich Kuhn /* SPDX-License-Identifier: BSD-3-Clause
219af5a38SHeinrich Kuhn * Copyright (c) 2014-2021 Netronome Systems, Inc.
319af5a38SHeinrich Kuhn * All rights reserved.
419af5a38SHeinrich Kuhn *
519af5a38SHeinrich Kuhn * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation.
619af5a38SHeinrich Kuhn */
719af5a38SHeinrich Kuhn
819af5a38SHeinrich Kuhn /*
919af5a38SHeinrich Kuhn * vim:shiftwidth=8:noexpandtab
1019af5a38SHeinrich Kuhn *
1119af5a38SHeinrich Kuhn * @file dpdk/pmd/nfp_cpp_bridge.c
1219af5a38SHeinrich Kuhn *
1319af5a38SHeinrich Kuhn * Netronome vNIC DPDK Poll-Mode Driver: CPP Bridge
1419af5a38SHeinrich Kuhn */
1519af5a38SHeinrich Kuhn
1619af5a38SHeinrich Kuhn #include <rte_service_component.h>
1719af5a38SHeinrich Kuhn
1819af5a38SHeinrich Kuhn #include "nfpcore/nfp_cpp.h"
1919af5a38SHeinrich Kuhn #include "nfpcore/nfp_mip.h"
2019af5a38SHeinrich Kuhn #include "nfpcore/nfp_nsp.h"
2119af5a38SHeinrich Kuhn
228d7a59f1SHeinrich Kuhn #include "nfp_logs.h"
2319af5a38SHeinrich Kuhn #include "nfp_cpp_bridge.h"
2419af5a38SHeinrich Kuhn
2519af5a38SHeinrich Kuhn #include <sys/ioctl.h>
2619af5a38SHeinrich Kuhn
2719af5a38SHeinrich Kuhn /* Prototypes */
2819af5a38SHeinrich Kuhn static int nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp);
2919af5a38SHeinrich Kuhn static int nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp);
3019af5a38SHeinrich Kuhn static int nfp_cpp_bridge_serve_ioctl(int sockfd, struct nfp_cpp *cpp);
3119af5a38SHeinrich Kuhn
nfp_register_cpp_service(struct nfp_cpp * cpp)3219af5a38SHeinrich Kuhn void nfp_register_cpp_service(struct nfp_cpp *cpp)
3319af5a38SHeinrich Kuhn {
3419af5a38SHeinrich Kuhn uint32_t *cpp_service_id = NULL;
3519af5a38SHeinrich Kuhn struct rte_service_spec service;
3619af5a38SHeinrich Kuhn
3719af5a38SHeinrich Kuhn memset(&service, 0, sizeof(struct rte_service_spec));
3819af5a38SHeinrich Kuhn snprintf(service.name, sizeof(service.name), "nfp_cpp_service");
3919af5a38SHeinrich Kuhn service.callback = nfp_cpp_bridge_service_func;
4019af5a38SHeinrich Kuhn service.callback_userdata = (void *)cpp;
4119af5a38SHeinrich Kuhn
4219af5a38SHeinrich Kuhn if (rte_service_component_register(&service,
4319af5a38SHeinrich Kuhn cpp_service_id))
4419af5a38SHeinrich Kuhn RTE_LOG(WARNING, PMD, "NFP CPP bridge service register() failed");
4519af5a38SHeinrich Kuhn else
4619af5a38SHeinrich Kuhn RTE_LOG(DEBUG, PMD, "NFP CPP bridge service registered");
4719af5a38SHeinrich Kuhn }
4819af5a38SHeinrich Kuhn
4919af5a38SHeinrich Kuhn /*
5019af5a38SHeinrich Kuhn * Serving a write request to NFP from host programs. The request
5119af5a38SHeinrich Kuhn * sends the write size and the CPP target. The bridge makes use
5219af5a38SHeinrich Kuhn * of CPP interface handler configured by the PMD setup.
5319af5a38SHeinrich Kuhn */
5419af5a38SHeinrich Kuhn static int
nfp_cpp_bridge_serve_write(int sockfd,struct nfp_cpp * cpp)5519af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp)
5619af5a38SHeinrich Kuhn {
5719af5a38SHeinrich Kuhn struct nfp_cpp_area *area;
5819af5a38SHeinrich Kuhn off_t offset, nfp_offset;
5919af5a38SHeinrich Kuhn uint32_t cpp_id, pos, len;
6019af5a38SHeinrich Kuhn uint32_t tmpbuf[16];
61*9465a5d5SConor Walsh size_t count, curlen;
6219af5a38SHeinrich Kuhn int err = 0;
6319af5a38SHeinrich Kuhn
6419af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu\n", __func__,
6519af5a38SHeinrich Kuhn sizeof(off_t), sizeof(size_t));
6619af5a38SHeinrich Kuhn
6719af5a38SHeinrich Kuhn /* Reading the count param */
6819af5a38SHeinrich Kuhn err = recv(sockfd, &count, sizeof(off_t), 0);
6919af5a38SHeinrich Kuhn if (err != sizeof(off_t))
7019af5a38SHeinrich Kuhn return -EINVAL;
7119af5a38SHeinrich Kuhn
7219af5a38SHeinrich Kuhn curlen = count;
7319af5a38SHeinrich Kuhn
7419af5a38SHeinrich Kuhn /* Reading the offset param */
7519af5a38SHeinrich Kuhn err = recv(sockfd, &offset, sizeof(off_t), 0);
7619af5a38SHeinrich Kuhn if (err != sizeof(off_t))
7719af5a38SHeinrich Kuhn return -EINVAL;
7819af5a38SHeinrich Kuhn
7919af5a38SHeinrich Kuhn /* Obtain target's CPP ID and offset in target */
8019af5a38SHeinrich Kuhn cpp_id = (offset >> 40) << 8;
8119af5a38SHeinrich Kuhn nfp_offset = offset & ((1ull << 40) - 1);
8219af5a38SHeinrich Kuhn
8319af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd\n", __func__, count,
8419af5a38SHeinrich Kuhn offset);
8519af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd\n", __func__,
8619af5a38SHeinrich Kuhn cpp_id, nfp_offset);
8719af5a38SHeinrich Kuhn
8819af5a38SHeinrich Kuhn /* Adjust length if not aligned */
8919af5a38SHeinrich Kuhn if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) !=
9019af5a38SHeinrich Kuhn (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) {
9119af5a38SHeinrich Kuhn curlen = NFP_CPP_MEMIO_BOUNDARY -
9219af5a38SHeinrich Kuhn (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1));
9319af5a38SHeinrich Kuhn }
9419af5a38SHeinrich Kuhn
9519af5a38SHeinrich Kuhn while (count > 0) {
9619af5a38SHeinrich Kuhn /* configure a CPP PCIe2CPP BAR for mapping the CPP target */
9719af5a38SHeinrich Kuhn area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev",
9819af5a38SHeinrich Kuhn nfp_offset, curlen);
9919af5a38SHeinrich Kuhn if (!area) {
10019af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: area alloc fail\n", __func__);
10119af5a38SHeinrich Kuhn return -EIO;
10219af5a38SHeinrich Kuhn }
10319af5a38SHeinrich Kuhn
10419af5a38SHeinrich Kuhn /* mapping the target */
10519af5a38SHeinrich Kuhn err = nfp_cpp_area_acquire(area);
10619af5a38SHeinrich Kuhn if (err < 0) {
10719af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "area acquire failed\n");
10819af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
10919af5a38SHeinrich Kuhn return -EIO;
11019af5a38SHeinrich Kuhn }
11119af5a38SHeinrich Kuhn
11219af5a38SHeinrich Kuhn for (pos = 0; pos < curlen; pos += len) {
11319af5a38SHeinrich Kuhn len = curlen - pos;
11419af5a38SHeinrich Kuhn if (len > sizeof(tmpbuf))
11519af5a38SHeinrich Kuhn len = sizeof(tmpbuf);
11619af5a38SHeinrich Kuhn
11719af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: Receive %u of %zu\n", __func__,
11819af5a38SHeinrich Kuhn len, count);
11919af5a38SHeinrich Kuhn err = recv(sockfd, tmpbuf, len, MSG_WAITALL);
12019af5a38SHeinrich Kuhn if (err != (int)len) {
12119af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD,
12219af5a38SHeinrich Kuhn "%s: error when receiving, %d of %zu\n",
12319af5a38SHeinrich Kuhn __func__, err, count);
12419af5a38SHeinrich Kuhn nfp_cpp_area_release(area);
12519af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
12619af5a38SHeinrich Kuhn return -EIO;
12719af5a38SHeinrich Kuhn }
12819af5a38SHeinrich Kuhn err = nfp_cpp_area_write(area, pos, tmpbuf, len);
12919af5a38SHeinrich Kuhn if (err < 0) {
13019af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "nfp_cpp_area_write error\n");
13119af5a38SHeinrich Kuhn nfp_cpp_area_release(area);
13219af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
13319af5a38SHeinrich Kuhn return -EIO;
13419af5a38SHeinrich Kuhn }
13519af5a38SHeinrich Kuhn }
13619af5a38SHeinrich Kuhn
13719af5a38SHeinrich Kuhn nfp_offset += pos;
13819af5a38SHeinrich Kuhn nfp_cpp_area_release(area);
13919af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
14019af5a38SHeinrich Kuhn
14119af5a38SHeinrich Kuhn count -= pos;
14219af5a38SHeinrich Kuhn curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ?
14319af5a38SHeinrich Kuhn NFP_CPP_MEMIO_BOUNDARY : count;
14419af5a38SHeinrich Kuhn }
14519af5a38SHeinrich Kuhn
14619af5a38SHeinrich Kuhn return 0;
14719af5a38SHeinrich Kuhn }
14819af5a38SHeinrich Kuhn
14919af5a38SHeinrich Kuhn /*
15019af5a38SHeinrich Kuhn * Serving a read request to NFP from host programs. The request
15119af5a38SHeinrich Kuhn * sends the read size and the CPP target. The bridge makes use
15219af5a38SHeinrich Kuhn * of CPP interface handler configured by the PMD setup. The read
15319af5a38SHeinrich Kuhn * data is sent to the requester using the same socket.
15419af5a38SHeinrich Kuhn */
15519af5a38SHeinrich Kuhn static int
nfp_cpp_bridge_serve_read(int sockfd,struct nfp_cpp * cpp)15619af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp)
15719af5a38SHeinrich Kuhn {
15819af5a38SHeinrich Kuhn struct nfp_cpp_area *area;
15919af5a38SHeinrich Kuhn off_t offset, nfp_offset;
16019af5a38SHeinrich Kuhn uint32_t cpp_id, pos, len;
16119af5a38SHeinrich Kuhn uint32_t tmpbuf[16];
162*9465a5d5SConor Walsh size_t count, curlen;
16319af5a38SHeinrich Kuhn int err = 0;
16419af5a38SHeinrich Kuhn
16519af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu\n", __func__,
16619af5a38SHeinrich Kuhn sizeof(off_t), sizeof(size_t));
16719af5a38SHeinrich Kuhn
16819af5a38SHeinrich Kuhn /* Reading the count param */
16919af5a38SHeinrich Kuhn err = recv(sockfd, &count, sizeof(off_t), 0);
17019af5a38SHeinrich Kuhn if (err != sizeof(off_t))
17119af5a38SHeinrich Kuhn return -EINVAL;
17219af5a38SHeinrich Kuhn
17319af5a38SHeinrich Kuhn curlen = count;
17419af5a38SHeinrich Kuhn
17519af5a38SHeinrich Kuhn /* Reading the offset param */
17619af5a38SHeinrich Kuhn err = recv(sockfd, &offset, sizeof(off_t), 0);
17719af5a38SHeinrich Kuhn if (err != sizeof(off_t))
17819af5a38SHeinrich Kuhn return -EINVAL;
17919af5a38SHeinrich Kuhn
18019af5a38SHeinrich Kuhn /* Obtain target's CPP ID and offset in target */
18119af5a38SHeinrich Kuhn cpp_id = (offset >> 40) << 8;
18219af5a38SHeinrich Kuhn nfp_offset = offset & ((1ull << 40) - 1);
18319af5a38SHeinrich Kuhn
18419af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd\n", __func__, count,
18519af5a38SHeinrich Kuhn offset);
18619af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd\n", __func__,
18719af5a38SHeinrich Kuhn cpp_id, nfp_offset);
18819af5a38SHeinrich Kuhn
18919af5a38SHeinrich Kuhn /* Adjust length if not aligned */
19019af5a38SHeinrich Kuhn if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) !=
19119af5a38SHeinrich Kuhn (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) {
19219af5a38SHeinrich Kuhn curlen = NFP_CPP_MEMIO_BOUNDARY -
19319af5a38SHeinrich Kuhn (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1));
19419af5a38SHeinrich Kuhn }
19519af5a38SHeinrich Kuhn
19619af5a38SHeinrich Kuhn while (count > 0) {
19719af5a38SHeinrich Kuhn area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev",
19819af5a38SHeinrich Kuhn nfp_offset, curlen);
19919af5a38SHeinrich Kuhn if (!area) {
20019af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: area alloc failed\n", __func__);
20119af5a38SHeinrich Kuhn return -EIO;
20219af5a38SHeinrich Kuhn }
20319af5a38SHeinrich Kuhn
20419af5a38SHeinrich Kuhn err = nfp_cpp_area_acquire(area);
20519af5a38SHeinrich Kuhn if (err < 0) {
20619af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "area acquire failed\n");
20719af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
20819af5a38SHeinrich Kuhn return -EIO;
20919af5a38SHeinrich Kuhn }
21019af5a38SHeinrich Kuhn
21119af5a38SHeinrich Kuhn for (pos = 0; pos < curlen; pos += len) {
21219af5a38SHeinrich Kuhn len = curlen - pos;
21319af5a38SHeinrich Kuhn if (len > sizeof(tmpbuf))
21419af5a38SHeinrich Kuhn len = sizeof(tmpbuf);
21519af5a38SHeinrich Kuhn
21619af5a38SHeinrich Kuhn err = nfp_cpp_area_read(area, pos, tmpbuf, len);
21719af5a38SHeinrich Kuhn if (err < 0) {
21819af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "nfp_cpp_area_read error\n");
21919af5a38SHeinrich Kuhn nfp_cpp_area_release(area);
22019af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
22119af5a38SHeinrich Kuhn return -EIO;
22219af5a38SHeinrich Kuhn }
22319af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: sending %u of %zu\n", __func__,
22419af5a38SHeinrich Kuhn len, count);
22519af5a38SHeinrich Kuhn
22619af5a38SHeinrich Kuhn err = send(sockfd, tmpbuf, len, 0);
22719af5a38SHeinrich Kuhn if (err != (int)len) {
22819af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD,
22919af5a38SHeinrich Kuhn "%s: error when sending: %d of %zu\n",
23019af5a38SHeinrich Kuhn __func__, err, count);
23119af5a38SHeinrich Kuhn nfp_cpp_area_release(area);
23219af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
23319af5a38SHeinrich Kuhn return -EIO;
23419af5a38SHeinrich Kuhn }
23519af5a38SHeinrich Kuhn }
23619af5a38SHeinrich Kuhn
23719af5a38SHeinrich Kuhn nfp_offset += pos;
23819af5a38SHeinrich Kuhn nfp_cpp_area_release(area);
23919af5a38SHeinrich Kuhn nfp_cpp_area_free(area);
24019af5a38SHeinrich Kuhn
24119af5a38SHeinrich Kuhn count -= pos;
24219af5a38SHeinrich Kuhn curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ?
24319af5a38SHeinrich Kuhn NFP_CPP_MEMIO_BOUNDARY : count;
24419af5a38SHeinrich Kuhn }
24519af5a38SHeinrich Kuhn return 0;
24619af5a38SHeinrich Kuhn }
24719af5a38SHeinrich Kuhn
24819af5a38SHeinrich Kuhn /*
24919af5a38SHeinrich Kuhn * Serving a ioctl command from host NFP tools. This usually goes to
25019af5a38SHeinrich Kuhn * a kernel driver char driver but it is not available when the PF is
25119af5a38SHeinrich Kuhn * bound to the PMD. Currently just one ioctl command is served and it
25219af5a38SHeinrich Kuhn * does not require any CPP access at all.
25319af5a38SHeinrich Kuhn */
25419af5a38SHeinrich Kuhn static int
nfp_cpp_bridge_serve_ioctl(int sockfd,struct nfp_cpp * cpp)25519af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_ioctl(int sockfd, struct nfp_cpp *cpp)
25619af5a38SHeinrich Kuhn {
25719af5a38SHeinrich Kuhn uint32_t cmd, ident_size, tmp;
25819af5a38SHeinrich Kuhn int err;
25919af5a38SHeinrich Kuhn
26019af5a38SHeinrich Kuhn /* Reading now the IOCTL command */
26119af5a38SHeinrich Kuhn err = recv(sockfd, &cmd, 4, 0);
26219af5a38SHeinrich Kuhn if (err != 4) {
26319af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: read error from socket\n", __func__);
26419af5a38SHeinrich Kuhn return -EIO;
26519af5a38SHeinrich Kuhn }
26619af5a38SHeinrich Kuhn
26719af5a38SHeinrich Kuhn /* Only supporting NFP_IOCTL_CPP_IDENTIFICATION */
26819af5a38SHeinrich Kuhn if (cmd != NFP_IOCTL_CPP_IDENTIFICATION) {
26919af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: unknown cmd %d\n", __func__, cmd);
27019af5a38SHeinrich Kuhn return -EINVAL;
27119af5a38SHeinrich Kuhn }
27219af5a38SHeinrich Kuhn
27319af5a38SHeinrich Kuhn err = recv(sockfd, &ident_size, 4, 0);
27419af5a38SHeinrich Kuhn if (err != 4) {
27519af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: read error from socket\n", __func__);
27619af5a38SHeinrich Kuhn return -EIO;
27719af5a38SHeinrich Kuhn }
27819af5a38SHeinrich Kuhn
27919af5a38SHeinrich Kuhn tmp = nfp_cpp_model(cpp);
28019af5a38SHeinrich Kuhn
28119af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: sending NFP model %08x\n", __func__, tmp);
28219af5a38SHeinrich Kuhn
28319af5a38SHeinrich Kuhn err = send(sockfd, &tmp, 4, 0);
28419af5a38SHeinrich Kuhn if (err != 4) {
28519af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: error writing to socket\n", __func__);
28619af5a38SHeinrich Kuhn return -EIO;
28719af5a38SHeinrich Kuhn }
28819af5a38SHeinrich Kuhn
28919af5a38SHeinrich Kuhn tmp = cpp->interface;
29019af5a38SHeinrich Kuhn
29119af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: sending NFP interface %08x\n", __func__, tmp);
29219af5a38SHeinrich Kuhn
29319af5a38SHeinrich Kuhn err = send(sockfd, &tmp, 4, 0);
29419af5a38SHeinrich Kuhn if (err != 4) {
29519af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: error writing to socket\n", __func__);
29619af5a38SHeinrich Kuhn return -EIO;
29719af5a38SHeinrich Kuhn }
29819af5a38SHeinrich Kuhn
29919af5a38SHeinrich Kuhn return 0;
30019af5a38SHeinrich Kuhn }
30119af5a38SHeinrich Kuhn
30219af5a38SHeinrich Kuhn /*
30319af5a38SHeinrich Kuhn * This is the code to be executed by a service core. The CPP bridge interface
30419af5a38SHeinrich Kuhn * is based on a unix socket and requests usually received by a kernel char
30519af5a38SHeinrich Kuhn * driver, read, write and ioctl, are handled by the CPP bridge. NFP host tools
30619af5a38SHeinrich Kuhn * can be executed with a wrapper library and LD_LIBRARY being completely
30719af5a38SHeinrich Kuhn * unaware of the CPP bridge performing the NFP kernel char driver for CPP
30819af5a38SHeinrich Kuhn * accesses.
30919af5a38SHeinrich Kuhn */
31019af5a38SHeinrich Kuhn int32_t
nfp_cpp_bridge_service_func(void * args)31119af5a38SHeinrich Kuhn nfp_cpp_bridge_service_func(void *args)
31219af5a38SHeinrich Kuhn {
31319af5a38SHeinrich Kuhn struct sockaddr address;
31419af5a38SHeinrich Kuhn struct nfp_cpp *cpp = args;
31519af5a38SHeinrich Kuhn int sockfd, datafd, op, ret;
31619af5a38SHeinrich Kuhn
31719af5a38SHeinrich Kuhn unlink("/tmp/nfp_cpp");
31819af5a38SHeinrich Kuhn sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
31919af5a38SHeinrich Kuhn if (sockfd < 0) {
32019af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: socket creation error. Service failed\n",
32119af5a38SHeinrich Kuhn __func__);
32219af5a38SHeinrich Kuhn return -EIO;
32319af5a38SHeinrich Kuhn }
32419af5a38SHeinrich Kuhn
32519af5a38SHeinrich Kuhn memset(&address, 0, sizeof(struct sockaddr));
32619af5a38SHeinrich Kuhn
32719af5a38SHeinrich Kuhn address.sa_family = AF_UNIX;
32819af5a38SHeinrich Kuhn strcpy(address.sa_data, "/tmp/nfp_cpp");
32919af5a38SHeinrich Kuhn
33019af5a38SHeinrich Kuhn ret = bind(sockfd, (const struct sockaddr *)&address,
33119af5a38SHeinrich Kuhn sizeof(struct sockaddr));
33219af5a38SHeinrich Kuhn if (ret < 0) {
33319af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: bind error (%d). Service failed\n",
33419af5a38SHeinrich Kuhn __func__, errno);
33519af5a38SHeinrich Kuhn close(sockfd);
33619af5a38SHeinrich Kuhn return ret;
33719af5a38SHeinrich Kuhn }
33819af5a38SHeinrich Kuhn
33919af5a38SHeinrich Kuhn ret = listen(sockfd, 20);
34019af5a38SHeinrich Kuhn if (ret < 0) {
34119af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: listen error(%d). Service failed\n",
34219af5a38SHeinrich Kuhn __func__, errno);
34319af5a38SHeinrich Kuhn close(sockfd);
34419af5a38SHeinrich Kuhn return ret;
34519af5a38SHeinrich Kuhn }
34619af5a38SHeinrich Kuhn
34719af5a38SHeinrich Kuhn for (;;) {
34819af5a38SHeinrich Kuhn datafd = accept(sockfd, NULL, NULL);
34919af5a38SHeinrich Kuhn if (datafd < 0) {
35019af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: accept call error (%d)\n",
35119af5a38SHeinrich Kuhn __func__, errno);
35219af5a38SHeinrich Kuhn RTE_LOG(ERR, PMD, "%s: service failed\n", __func__);
35319af5a38SHeinrich Kuhn close(sockfd);
35419af5a38SHeinrich Kuhn return -EIO;
35519af5a38SHeinrich Kuhn }
35619af5a38SHeinrich Kuhn
35719af5a38SHeinrich Kuhn while (1) {
35819af5a38SHeinrich Kuhn ret = recv(datafd, &op, 4, 0);
35919af5a38SHeinrich Kuhn if (ret <= 0) {
36019af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: socket close\n",
36119af5a38SHeinrich Kuhn __func__);
36219af5a38SHeinrich Kuhn break;
36319af5a38SHeinrich Kuhn }
36419af5a38SHeinrich Kuhn
36519af5a38SHeinrich Kuhn PMD_CPP_LOG(DEBUG, "%s: getting op %u\n", __func__, op);
36619af5a38SHeinrich Kuhn
36719af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_READ)
36819af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_read(datafd, cpp);
36919af5a38SHeinrich Kuhn
37019af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_WRITE)
37119af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_write(datafd, cpp);
37219af5a38SHeinrich Kuhn
37319af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_IOCTL)
37419af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_ioctl(datafd, cpp);
37519af5a38SHeinrich Kuhn
37619af5a38SHeinrich Kuhn if (op == 0)
37719af5a38SHeinrich Kuhn break;
37819af5a38SHeinrich Kuhn }
37919af5a38SHeinrich Kuhn close(datafd);
38019af5a38SHeinrich Kuhn }
38119af5a38SHeinrich Kuhn close(sockfd);
38219af5a38SHeinrich Kuhn
38319af5a38SHeinrich Kuhn return 0;
38419af5a38SHeinrich Kuhn }
38519af5a38SHeinrich Kuhn /*
38619af5a38SHeinrich Kuhn * Local variables:
38719af5a38SHeinrich Kuhn * c-file-style: "Linux"
38819af5a38SHeinrich Kuhn * indent-tabs-mode: t
38919af5a38SHeinrich Kuhn * End:
39019af5a38SHeinrich Kuhn */
391