From: Heinrich Kuhn Date: Thu, 29 Jul 2021 13:47:07 +0000 (+0200) Subject: net/nfp: move CPP bridge to separate file X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=19af5a38f7b600e9c57d3ea235c2108b3c542a81;p=dpdk.git net/nfp: move CPP bridge to separate file This commit moves the CPP bridge logic to a separate file. A new corresponding header file is also created. Signed-off-by: Heinrich Kuhn Signed-off-by: Simon Horman --- diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build index 1b289e2354..b46ac2d40f 100644 --- a/drivers/net/nfp/meson.build +++ b/drivers/net/nfp/meson.build @@ -20,4 +20,5 @@ sources = files( 'nfpcore/nfp_hwinfo.c', 'nfp_net.c', 'nfp_rxtx.c', + 'nfp_cpp_bridge.c', ) diff --git a/drivers/net/nfp/nfp_cpp_bridge.c b/drivers/net/nfp/nfp_cpp_bridge.c new file mode 100644 index 0000000000..d916793338 --- /dev/null +++ b/drivers/net/nfp/nfp_cpp_bridge.c @@ -0,0 +1,392 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2021 Netronome Systems, Inc. + * All rights reserved. + * + * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation. + */ + +/* + * vim:shiftwidth=8:noexpandtab + * + * @file dpdk/pmd/nfp_cpp_bridge.c + * + * Netronome vNIC DPDK Poll-Mode Driver: CPP Bridge + */ + +#include + +#include "nfpcore/nfp_cpp.h" +#include "nfpcore/nfp_mip.h" +#include "nfpcore/nfp_nsp.h" + +#include "nfp_net_logs.h" +#include "nfp_cpp_bridge.h" + +#include + +/* Prototypes */ +static int nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp); +static int nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp); +static int nfp_cpp_bridge_serve_ioctl(int sockfd, struct nfp_cpp *cpp); + +void nfp_register_cpp_service(struct nfp_cpp *cpp) +{ + uint32_t *cpp_service_id = NULL; + struct rte_service_spec service; + + memset(&service, 0, sizeof(struct rte_service_spec)); + snprintf(service.name, sizeof(service.name), "nfp_cpp_service"); + service.callback = nfp_cpp_bridge_service_func; + service.callback_userdata = (void *)cpp; + + if (rte_service_component_register(&service, + cpp_service_id)) + RTE_LOG(WARNING, PMD, "NFP CPP bridge service register() failed"); + else + RTE_LOG(DEBUG, PMD, "NFP CPP bridge service registered"); +} + +/* + * Serving a write request to NFP from host programs. The request + * sends the write size and the CPP target. The bridge makes use + * of CPP interface handler configured by the PMD setup. + */ +static int +nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) +{ + struct nfp_cpp_area *area; + off_t offset, nfp_offset; + uint32_t cpp_id, pos, len; + uint32_t tmpbuf[16]; + size_t count, curlen, totlen = 0; + int err = 0; + + PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu\n", __func__, + sizeof(off_t), sizeof(size_t)); + + /* Reading the count param */ + err = recv(sockfd, &count, sizeof(off_t), 0); + if (err != sizeof(off_t)) + return -EINVAL; + + curlen = count; + + /* Reading the offset param */ + err = recv(sockfd, &offset, sizeof(off_t), 0); + if (err != sizeof(off_t)) + return -EINVAL; + + /* Obtain target's CPP ID and offset in target */ + cpp_id = (offset >> 40) << 8; + nfp_offset = offset & ((1ull << 40) - 1); + + PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd\n", __func__, count, + offset); + PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd\n", __func__, + cpp_id, nfp_offset); + + /* Adjust length if not aligned */ + if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != + (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { + curlen = NFP_CPP_MEMIO_BOUNDARY - + (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); + } + + while (count > 0) { + /* configure a CPP PCIe2CPP BAR for mapping the CPP target */ + area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", + nfp_offset, curlen); + if (!area) { + RTE_LOG(ERR, PMD, "%s: area alloc fail\n", __func__); + return -EIO; + } + + /* mapping the target */ + err = nfp_cpp_area_acquire(area); + if (err < 0) { + RTE_LOG(ERR, PMD, "area acquire failed\n"); + nfp_cpp_area_free(area); + return -EIO; + } + + for (pos = 0; pos < curlen; pos += len) { + len = curlen - pos; + if (len > sizeof(tmpbuf)) + len = sizeof(tmpbuf); + + PMD_CPP_LOG(DEBUG, "%s: Receive %u of %zu\n", __func__, + len, count); + err = recv(sockfd, tmpbuf, len, MSG_WAITALL); + if (err != (int)len) { + RTE_LOG(ERR, PMD, + "%s: error when receiving, %d of %zu\n", + __func__, err, count); + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + return -EIO; + } + err = nfp_cpp_area_write(area, pos, tmpbuf, len); + if (err < 0) { + RTE_LOG(ERR, PMD, "nfp_cpp_area_write error\n"); + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + return -EIO; + } + } + + nfp_offset += pos; + totlen += pos; + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + + count -= pos; + curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? + NFP_CPP_MEMIO_BOUNDARY : count; + } + + return 0; +} + +/* + * Serving a read request to NFP from host programs. The request + * sends the read size and the CPP target. The bridge makes use + * of CPP interface handler configured by the PMD setup. The read + * data is sent to the requester using the same socket. + */ +static int +nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) +{ + struct nfp_cpp_area *area; + off_t offset, nfp_offset; + uint32_t cpp_id, pos, len; + uint32_t tmpbuf[16]; + size_t count, curlen, totlen = 0; + int err = 0; + + PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu\n", __func__, + sizeof(off_t), sizeof(size_t)); + + /* Reading the count param */ + err = recv(sockfd, &count, sizeof(off_t), 0); + if (err != sizeof(off_t)) + return -EINVAL; + + curlen = count; + + /* Reading the offset param */ + err = recv(sockfd, &offset, sizeof(off_t), 0); + if (err != sizeof(off_t)) + return -EINVAL; + + /* Obtain target's CPP ID and offset in target */ + cpp_id = (offset >> 40) << 8; + nfp_offset = offset & ((1ull << 40) - 1); + + PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd\n", __func__, count, + offset); + PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd\n", __func__, + cpp_id, nfp_offset); + + /* Adjust length if not aligned */ + if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != + (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { + curlen = NFP_CPP_MEMIO_BOUNDARY - + (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); + } + + while (count > 0) { + area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", + nfp_offset, curlen); + if (!area) { + RTE_LOG(ERR, PMD, "%s: area alloc failed\n", __func__); + return -EIO; + } + + err = nfp_cpp_area_acquire(area); + if (err < 0) { + RTE_LOG(ERR, PMD, "area acquire failed\n"); + nfp_cpp_area_free(area); + return -EIO; + } + + for (pos = 0; pos < curlen; pos += len) { + len = curlen - pos; + if (len > sizeof(tmpbuf)) + len = sizeof(tmpbuf); + + err = nfp_cpp_area_read(area, pos, tmpbuf, len); + if (err < 0) { + RTE_LOG(ERR, PMD, "nfp_cpp_area_read error\n"); + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + return -EIO; + } + PMD_CPP_LOG(DEBUG, "%s: sending %u of %zu\n", __func__, + len, count); + + err = send(sockfd, tmpbuf, len, 0); + if (err != (int)len) { + RTE_LOG(ERR, PMD, + "%s: error when sending: %d of %zu\n", + __func__, err, count); + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + return -EIO; + } + } + + nfp_offset += pos; + totlen += pos; + nfp_cpp_area_release(area); + nfp_cpp_area_free(area); + + count -= pos; + curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? + NFP_CPP_MEMIO_BOUNDARY : count; + } + return 0; +} + +/* + * Serving a ioctl command from host NFP tools. This usually goes to + * a kernel driver char driver but it is not available when the PF is + * bound to the PMD. Currently just one ioctl command is served and it + * does not require any CPP access at all. + */ +static int +nfp_cpp_bridge_serve_ioctl(int sockfd, struct nfp_cpp *cpp) +{ + uint32_t cmd, ident_size, tmp; + int err; + + /* Reading now the IOCTL command */ + err = recv(sockfd, &cmd, 4, 0); + if (err != 4) { + RTE_LOG(ERR, PMD, "%s: read error from socket\n", __func__); + return -EIO; + } + + /* Only supporting NFP_IOCTL_CPP_IDENTIFICATION */ + if (cmd != NFP_IOCTL_CPP_IDENTIFICATION) { + RTE_LOG(ERR, PMD, "%s: unknown cmd %d\n", __func__, cmd); + return -EINVAL; + } + + err = recv(sockfd, &ident_size, 4, 0); + if (err != 4) { + RTE_LOG(ERR, PMD, "%s: read error from socket\n", __func__); + return -EIO; + } + + tmp = nfp_cpp_model(cpp); + + PMD_CPP_LOG(DEBUG, "%s: sending NFP model %08x\n", __func__, tmp); + + err = send(sockfd, &tmp, 4, 0); + if (err != 4) { + RTE_LOG(ERR, PMD, "%s: error writing to socket\n", __func__); + return -EIO; + } + + tmp = cpp->interface; + + PMD_CPP_LOG(DEBUG, "%s: sending NFP interface %08x\n", __func__, tmp); + + err = send(sockfd, &tmp, 4, 0); + if (err != 4) { + RTE_LOG(ERR, PMD, "%s: error writing to socket\n", __func__); + return -EIO; + } + + return 0; +} + +/* + * This is the code to be executed by a service core. The CPP bridge interface + * is based on a unix socket and requests usually received by a kernel char + * driver, read, write and ioctl, are handled by the CPP bridge. NFP host tools + * can be executed with a wrapper library and LD_LIBRARY being completely + * unaware of the CPP bridge performing the NFP kernel char driver for CPP + * accesses. + */ +int32_t +nfp_cpp_bridge_service_func(void *args) +{ + struct sockaddr address; + struct nfp_cpp *cpp = args; + int sockfd, datafd, op, ret; + + unlink("/tmp/nfp_cpp"); + sockfd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sockfd < 0) { + RTE_LOG(ERR, PMD, "%s: socket creation error. Service failed\n", + __func__); + return -EIO; + } + + memset(&address, 0, sizeof(struct sockaddr)); + + address.sa_family = AF_UNIX; + strcpy(address.sa_data, "/tmp/nfp_cpp"); + + ret = bind(sockfd, (const struct sockaddr *)&address, + sizeof(struct sockaddr)); + if (ret < 0) { + RTE_LOG(ERR, PMD, "%s: bind error (%d). Service failed\n", + __func__, errno); + close(sockfd); + return ret; + } + + ret = listen(sockfd, 20); + if (ret < 0) { + RTE_LOG(ERR, PMD, "%s: listen error(%d). Service failed\n", + __func__, errno); + close(sockfd); + return ret; + } + + for (;;) { + datafd = accept(sockfd, NULL, NULL); + if (datafd < 0) { + RTE_LOG(ERR, PMD, "%s: accept call error (%d)\n", + __func__, errno); + RTE_LOG(ERR, PMD, "%s: service failed\n", __func__); + close(sockfd); + return -EIO; + } + + while (1) { + ret = recv(datafd, &op, 4, 0); + if (ret <= 0) { + PMD_CPP_LOG(DEBUG, "%s: socket close\n", + __func__); + break; + } + + PMD_CPP_LOG(DEBUG, "%s: getting op %u\n", __func__, op); + + if (op == NFP_BRIDGE_OP_READ) + nfp_cpp_bridge_serve_read(datafd, cpp); + + if (op == NFP_BRIDGE_OP_WRITE) + nfp_cpp_bridge_serve_write(datafd, cpp); + + if (op == NFP_BRIDGE_OP_IOCTL) + nfp_cpp_bridge_serve_ioctl(datafd, cpp); + + if (op == 0) + break; + } + close(datafd); + } + close(sockfd); + + return 0; +} +/* + * Local variables: + * c-file-style: "Linux" + * indent-tabs-mode: t + * End: + */ diff --git a/drivers/net/nfp/nfp_cpp_bridge.h b/drivers/net/nfp/nfp_cpp_bridge.h new file mode 100644 index 0000000000..aea5fdc784 --- /dev/null +++ b/drivers/net/nfp/nfp_cpp_bridge.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) 2014-2021 Netronome Systems, Inc. + * All rights reserved. + * + * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation. + */ + +/* + * vim:shiftwidth=8:noexpandtab + * + * @file dpdk/pmd/nfp_cpp_bridge.h + * + * Netronome vNIC DPDK Poll-Mode Driver: CPP Bridge header file + */ + +#ifndef _NFP_CPP_BRIDGE_H_ +#define _NFP_CPP_BRIDGE_H_ + +#define NFP_CPP_MEMIO_BOUNDARY (1 << 20) +#define NFP_BRIDGE_OP_READ 20 +#define NFP_BRIDGE_OP_WRITE 30 +#define NFP_BRIDGE_OP_IOCTL 40 + +#define NFP_IOCTL 'n' +#define NFP_IOCTL_CPP_IDENTIFICATION _IOW(NFP_IOCTL, 0x8f, uint32_t) + +void nfp_register_cpp_service(struct nfp_cpp *cpp); +int32_t nfp_cpp_bridge_service_func(void *args); + +#endif /* _NFP_CPP_BRIDGE_H_ */ +/* + * Local variables: + * c-file-style: "Linux" + * indent-tabs-mode: t + * End: + */ diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c index de0de808f4..af94219729 100644 --- a/drivers/net/nfp/nfp_net.c +++ b/drivers/net/nfp/nfp_net.c @@ -43,6 +43,7 @@ #include "nfp_rxtx.h" #include "nfp_net_logs.h" #include "nfp_net_ctrl.h" +#include "nfp_cpp_bridge.h" #include #include @@ -83,8 +84,6 @@ static int nfp_net_rss_hash_write(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf); static int nfp_set_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr); -static int32_t nfp_cpp_bridge_service_func(void *args); -static void nfp_register_cpp_service(struct nfp_cpp *cpp); static int nfp_fw_setup(struct rte_pci_device *dev, struct nfp_cpp *cpp, struct nfp_eth_table *nfp_eth_table, @@ -1928,353 +1927,6 @@ dev_err_ctrl_map: return err; } -#define NFP_CPP_MEMIO_BOUNDARY (1 << 20) - -/* - * Serving a write request to NFP from host programs. The request - * sends the write size and the CPP target. The bridge makes use - * of CPP interface handler configured by the PMD setup. - */ -static int -nfp_cpp_bridge_serve_write(int sockfd, struct nfp_cpp *cpp) -{ - struct nfp_cpp_area *area; - off_t offset, nfp_offset; - uint32_t cpp_id, pos, len; - uint32_t tmpbuf[16]; - size_t count, curlen, totlen = 0; - int err = 0; - - PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu\n", __func__, - sizeof(off_t), sizeof(size_t)); - - /* Reading the count param */ - err = recv(sockfd, &count, sizeof(off_t), 0); - if (err != sizeof(off_t)) - return -EINVAL; - - curlen = count; - - /* Reading the offset param */ - err = recv(sockfd, &offset, sizeof(off_t), 0); - if (err != sizeof(off_t)) - return -EINVAL; - - /* Obtain target's CPP ID and offset in target */ - cpp_id = (offset >> 40) << 8; - nfp_offset = offset & ((1ull << 40) - 1); - - PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd\n", __func__, count, - offset); - PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd\n", __func__, - cpp_id, nfp_offset); - - /* Adjust length if not aligned */ - if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != - (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { - curlen = NFP_CPP_MEMIO_BOUNDARY - - (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); - } - - while (count > 0) { - /* configure a CPP PCIe2CPP BAR for mapping the CPP target */ - area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", - nfp_offset, curlen); - if (!area) { - RTE_LOG(ERR, PMD, "%s: area alloc fail\n", __func__); - return -EIO; - } - - /* mapping the target */ - err = nfp_cpp_area_acquire(area); - if (err < 0) { - RTE_LOG(ERR, PMD, "area acquire failed\n"); - nfp_cpp_area_free(area); - return -EIO; - } - - for (pos = 0; pos < curlen; pos += len) { - len = curlen - pos; - if (len > sizeof(tmpbuf)) - len = sizeof(tmpbuf); - - PMD_CPP_LOG(DEBUG, "%s: Receive %u of %zu\n", __func__, - len, count); - err = recv(sockfd, tmpbuf, len, MSG_WAITALL); - if (err != (int)len) { - RTE_LOG(ERR, PMD, - "%s: error when receiving, %d of %zu\n", - __func__, err, count); - nfp_cpp_area_release(area); - nfp_cpp_area_free(area); - return -EIO; - } - err = nfp_cpp_area_write(area, pos, tmpbuf, len); - if (err < 0) { - RTE_LOG(ERR, PMD, "nfp_cpp_area_write error\n"); - nfp_cpp_area_release(area); - nfp_cpp_area_free(area); - return -EIO; - } - } - - nfp_offset += pos; - totlen += pos; - nfp_cpp_area_release(area); - nfp_cpp_area_free(area); - - count -= pos; - curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? - NFP_CPP_MEMIO_BOUNDARY : count; - } - - return 0; -} - -/* - * Serving a read request to NFP from host programs. The request - * sends the read size and the CPP target. The bridge makes use - * of CPP interface handler configured by the PMD setup. The read - * data is sent to the requester using the same socket. - */ -static int -nfp_cpp_bridge_serve_read(int sockfd, struct nfp_cpp *cpp) -{ - struct nfp_cpp_area *area; - off_t offset, nfp_offset; - uint32_t cpp_id, pos, len; - uint32_t tmpbuf[16]; - size_t count, curlen, totlen = 0; - int err = 0; - - PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu\n", __func__, - sizeof(off_t), sizeof(size_t)); - - /* Reading the count param */ - err = recv(sockfd, &count, sizeof(off_t), 0); - if (err != sizeof(off_t)) - return -EINVAL; - - curlen = count; - - /* Reading the offset param */ - err = recv(sockfd, &offset, sizeof(off_t), 0); - if (err != sizeof(off_t)) - return -EINVAL; - - /* Obtain target's CPP ID and offset in target */ - cpp_id = (offset >> 40) << 8; - nfp_offset = offset & ((1ull << 40) - 1); - - PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd\n", __func__, count, - offset); - PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd\n", __func__, - cpp_id, nfp_offset); - - /* Adjust length if not aligned */ - if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != - (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { - curlen = NFP_CPP_MEMIO_BOUNDARY - - (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); - } - - while (count > 0) { - area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", - nfp_offset, curlen); - if (!area) { - RTE_LOG(ERR, PMD, "%s: area alloc failed\n", __func__); - return -EIO; - } - - err = nfp_cpp_area_acquire(area); - if (err < 0) { - RTE_LOG(ERR, PMD, "area acquire failed\n"); - nfp_cpp_area_free(area); - return -EIO; - } - - for (pos = 0; pos < curlen; pos += len) { - len = curlen - pos; - if (len > sizeof(tmpbuf)) - len = sizeof(tmpbuf); - - err = nfp_cpp_area_read(area, pos, tmpbuf, len); - if (err < 0) { - RTE_LOG(ERR, PMD, "nfp_cpp_area_read error\n"); - nfp_cpp_area_release(area); - nfp_cpp_area_free(area); - return -EIO; - } - PMD_CPP_LOG(DEBUG, "%s: sending %u of %zu\n", __func__, - len, count); - - err = send(sockfd, tmpbuf, len, 0); - if (err != (int)len) { - RTE_LOG(ERR, PMD, - "%s: error when sending: %d of %zu\n", - __func__, err, count); - nfp_cpp_area_release(area); - nfp_cpp_area_free(area); - return -EIO; - } - } - - nfp_offset += pos; - totlen += pos; - nfp_cpp_area_release(area); - nfp_cpp_area_free(area); - - count -= pos; - curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? - NFP_CPP_MEMIO_BOUNDARY : count; - } - return 0; -} - -#define NFP_IOCTL 'n' -#define NFP_IOCTL_CPP_IDENTIFICATION _IOW(NFP_IOCTL, 0x8f, uint32_t) -/* - * Serving a ioctl command from host NFP tools. This usually goes to - * a kernel driver char driver but it is not available when the PF is - * bound to the PMD. Currently just one ioctl command is served and it - * does not require any CPP access at all. - */ -static int -nfp_cpp_bridge_serve_ioctl(int sockfd, struct nfp_cpp *cpp) -{ - uint32_t cmd, ident_size, tmp; - int err; - - /* Reading now the IOCTL command */ - err = recv(sockfd, &cmd, 4, 0); - if (err != 4) { - RTE_LOG(ERR, PMD, "%s: read error from socket\n", __func__); - return -EIO; - } - - /* Only supporting NFP_IOCTL_CPP_IDENTIFICATION */ - if (cmd != NFP_IOCTL_CPP_IDENTIFICATION) { - RTE_LOG(ERR, PMD, "%s: unknown cmd %d\n", __func__, cmd); - return -EINVAL; - } - - err = recv(sockfd, &ident_size, 4, 0); - if (err != 4) { - RTE_LOG(ERR, PMD, "%s: read error from socket\n", __func__); - return -EIO; - } - - tmp = nfp_cpp_model(cpp); - - PMD_CPP_LOG(DEBUG, "%s: sending NFP model %08x\n", __func__, tmp); - - err = send(sockfd, &tmp, 4, 0); - if (err != 4) { - RTE_LOG(ERR, PMD, "%s: error writing to socket\n", __func__); - return -EIO; - } - - tmp = cpp->interface; - - PMD_CPP_LOG(DEBUG, "%s: sending NFP interface %08x\n", __func__, tmp); - - err = send(sockfd, &tmp, 4, 0); - if (err != 4) { - RTE_LOG(ERR, PMD, "%s: error writing to socket\n", __func__); - return -EIO; - } - - return 0; -} - -#define NFP_BRIDGE_OP_READ 20 -#define NFP_BRIDGE_OP_WRITE 30 -#define NFP_BRIDGE_OP_IOCTL 40 - -/* - * This is the code to be executed by a service core. The CPP bridge interface - * is based on a unix socket and requests usually received by a kernel char - * driver, read, write and ioctl, are handled by the CPP bridge. NFP host tools - * can be executed with a wrapper library and LD_LIBRARY being completely - * unaware of the CPP bridge performing the NFP kernel char driver for CPP - * accesses. - */ -static int32_t -nfp_cpp_bridge_service_func(void *args) -{ - struct sockaddr address; - struct nfp_cpp *cpp = args; - int sockfd, datafd, op, ret; - - unlink("/tmp/nfp_cpp"); - sockfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sockfd < 0) { - RTE_LOG(ERR, PMD, "%s: socket creation error. Service failed\n", - __func__); - return -EIO; - } - - memset(&address, 0, sizeof(struct sockaddr)); - - address.sa_family = AF_UNIX; - strcpy(address.sa_data, "/tmp/nfp_cpp"); - - ret = bind(sockfd, (const struct sockaddr *)&address, - sizeof(struct sockaddr)); - if (ret < 0) { - RTE_LOG(ERR, PMD, "%s: bind error (%d). Service failed\n", - __func__, errno); - close(sockfd); - return ret; - } - - ret = listen(sockfd, 20); - if (ret < 0) { - RTE_LOG(ERR, PMD, "%s: listen error(%d). Service failed\n", - __func__, errno); - close(sockfd); - return ret; - } - - for (;;) { - datafd = accept(sockfd, NULL, NULL); - if (datafd < 0) { - RTE_LOG(ERR, PMD, "%s: accept call error (%d)\n", - __func__, errno); - RTE_LOG(ERR, PMD, "%s: service failed\n", __func__); - close(sockfd); - return -EIO; - } - - while (1) { - ret = recv(datafd, &op, 4, 0); - if (ret <= 0) { - PMD_CPP_LOG(DEBUG, "%s: socket close\n", - __func__); - break; - } - - PMD_CPP_LOG(DEBUG, "%s: getting op %u\n", __func__, op); - - if (op == NFP_BRIDGE_OP_READ) - nfp_cpp_bridge_serve_read(datafd, cpp); - - if (op == NFP_BRIDGE_OP_WRITE) - nfp_cpp_bridge_serve_write(datafd, cpp); - - if (op == NFP_BRIDGE_OP_IOCTL) - nfp_cpp_bridge_serve_ioctl(datafd, cpp); - - if (op == 0) - break; - } - close(datafd); - } - close(sockfd); - - return 0; -} - #define DEFAULT_FW_PATH "/lib/firmware/netronome" static int @@ -2459,23 +2111,6 @@ error: return ret; } -static void nfp_register_cpp_service(struct nfp_cpp *cpp) -{ - uint32_t *cpp_service_id = NULL; - struct rte_service_spec service; - - memset(&service, 0, sizeof(struct rte_service_spec)); - snprintf(service.name, sizeof(service.name), "nfp_cpp_service"); - service.callback = nfp_cpp_bridge_service_func; - service.callback_userdata = (void *)cpp; - - if (rte_service_component_register(&service, - cpp_service_id)) - RTE_LOG(WARNING, PMD, "NFP CPP bridge service register() failed"); - else - RTE_LOG(DEBUG, PMD, "NFP CPP bridge service registered"); -} - static int nfp_pf_init(struct rte_pci_device *pci_dev) { struct nfp_pf_dev *pf_dev = NULL;