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 6f1523facSChaoyong He #include "nfp_cpp_bridge.h" 7f1523facSChaoyong He 88987de81SChaoyong He #include <unistd.h> 98987de81SChaoyong He #include <sys/ioctl.h> 108987de81SChaoyong He 1119af5a38SHeinrich Kuhn #include "nfpcore/nfp_cpp.h" 128d7a59f1SHeinrich Kuhn #include "nfp_logs.h" 13*600f6d2cSLong Wu #include "nfp_service.h" 14f1523facSChaoyong He 15f1523facSChaoyong He #define NFP_CPP_MEMIO_BOUNDARY (1 << 20) 16f1523facSChaoyong He #define NFP_BRIDGE_OP_READ 20 17f1523facSChaoyong He #define NFP_BRIDGE_OP_WRITE 30 18f1523facSChaoyong He #define NFP_BRIDGE_OP_IOCTL 40 19f1523facSChaoyong He 20f1523facSChaoyong He #define NFP_IOCTL 'n' 21f1523facSChaoyong He #define NFP_IOCTL_CPP_IDENTIFICATION _IOW(NFP_IOCTL, 0x8f, uint32_t) 2219af5a38SHeinrich Kuhn 2319af5a38SHeinrich Kuhn /* Prototypes */ 24b1880421SChaoyong He static int nfp_cpp_bridge_service_func(void *args); 2519af5a38SHeinrich Kuhn 26b1880421SChaoyong He int 27bab0e6f4SChaoyong He nfp_enable_cpp_service(struct nfp_pf_dev *pf_dev) 28b1880421SChaoyong He { 29b1880421SChaoyong He int ret; 30*600f6d2cSLong Wu const char *pci_name; 31b1880421SChaoyong He struct rte_service_spec cpp_service = { 32b1880421SChaoyong He .callback = nfp_cpp_bridge_service_func, 33*600f6d2cSLong Wu .callback_userdata = (void *)pf_dev, 34b1880421SChaoyong He }; 35b1880421SChaoyong He 36*600f6d2cSLong Wu pci_name = strchr(pf_dev->pci_dev->name, ':') + 1; 37*600f6d2cSLong Wu snprintf(cpp_service.name, sizeof(cpp_service.name), "%s_cpp_service", pci_name); 38b1880421SChaoyong He 39*600f6d2cSLong Wu ret = nfp_service_enable(&cpp_service, &pf_dev->cpp_service_info); 40b1880421SChaoyong He if (ret != 0) { 41*600f6d2cSLong Wu PMD_INIT_LOG(DEBUG, "Could not enable service %s", cpp_service.name); 42*600f6d2cSLong Wu return ret; 43b1880421SChaoyong He } 44b1880421SChaoyong He 45b1880421SChaoyong He return 0; 4619af5a38SHeinrich Kuhn } 4719af5a38SHeinrich Kuhn 4819af5a38SHeinrich Kuhn /* 4919af5a38SHeinrich Kuhn * Serving a write request to NFP from host programs. The request 5019af5a38SHeinrich Kuhn * sends the write size and the CPP target. The bridge makes use 5119af5a38SHeinrich Kuhn * of CPP interface handler configured by the PMD setup. 5219af5a38SHeinrich Kuhn */ 5319af5a38SHeinrich Kuhn static int 54f4d24fe9SChaoyong He nfp_cpp_bridge_serve_write(int sockfd, 55f4d24fe9SChaoyong He struct nfp_cpp *cpp) 5619af5a38SHeinrich Kuhn { 5749952141SChaoyong He int err; 5849952141SChaoyong He off_t offset; 5949952141SChaoyong He uint32_t pos; 6049952141SChaoyong He uint32_t len; 6149952141SChaoyong He size_t count; 6249952141SChaoyong He size_t curlen; 6349952141SChaoyong He uint32_t cpp_id; 6449952141SChaoyong He off_t nfp_offset; 6519af5a38SHeinrich Kuhn uint32_t tmpbuf[16]; 6649952141SChaoyong He struct nfp_cpp_area *area; 6719af5a38SHeinrich Kuhn 68030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu", __func__, 6919af5a38SHeinrich Kuhn sizeof(off_t), sizeof(size_t)); 7019af5a38SHeinrich Kuhn 7119af5a38SHeinrich Kuhn /* Reading the count param */ 7219af5a38SHeinrich Kuhn err = recv(sockfd, &count, sizeof(off_t), 0); 7319af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 7419af5a38SHeinrich Kuhn return -EINVAL; 7519af5a38SHeinrich Kuhn 7619af5a38SHeinrich Kuhn curlen = count; 7719af5a38SHeinrich Kuhn 7819af5a38SHeinrich Kuhn /* Reading the offset param */ 7919af5a38SHeinrich Kuhn err = recv(sockfd, &offset, sizeof(off_t), 0); 8019af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 8119af5a38SHeinrich Kuhn return -EINVAL; 8219af5a38SHeinrich Kuhn 8319af5a38SHeinrich Kuhn /* Obtain target's CPP ID and offset in target */ 8419af5a38SHeinrich Kuhn cpp_id = (offset >> 40) << 8; 8519af5a38SHeinrich Kuhn nfp_offset = offset & ((1ull << 40) - 1); 8619af5a38SHeinrich Kuhn 87030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd", __func__, count, 8819af5a38SHeinrich Kuhn offset); 89030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd", __func__, 9019af5a38SHeinrich Kuhn cpp_id, nfp_offset); 9119af5a38SHeinrich Kuhn 9219af5a38SHeinrich Kuhn /* Adjust length if not aligned */ 9319af5a38SHeinrich Kuhn if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != 9419af5a38SHeinrich Kuhn (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { 9519af5a38SHeinrich Kuhn curlen = NFP_CPP_MEMIO_BOUNDARY - 9619af5a38SHeinrich Kuhn (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); 9719af5a38SHeinrich Kuhn } 9819af5a38SHeinrich Kuhn 9919af5a38SHeinrich Kuhn while (count > 0) { 100030b2b19SChaoyong He /* Configure a CPP PCIe2CPP BAR for mapping the CPP target */ 10119af5a38SHeinrich Kuhn area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", 10219af5a38SHeinrich Kuhn nfp_offset, curlen); 103cbcbfd73SJames Hershaw if (area == NULL) { 10454fdb550SChaoyong He PMD_CPP_LOG(ERR, "area alloc fail"); 10519af5a38SHeinrich Kuhn return -EIO; 10619af5a38SHeinrich Kuhn } 10719af5a38SHeinrich Kuhn 108030b2b19SChaoyong He /* Mapping the target */ 10919af5a38SHeinrich Kuhn err = nfp_cpp_area_acquire(area); 11019af5a38SHeinrich Kuhn if (err < 0) { 11154fdb550SChaoyong He PMD_CPP_LOG(ERR, "area acquire failed"); 11219af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 11319af5a38SHeinrich Kuhn return -EIO; 11419af5a38SHeinrich Kuhn } 11519af5a38SHeinrich Kuhn 11619af5a38SHeinrich Kuhn for (pos = 0; pos < curlen; pos += len) { 11719af5a38SHeinrich Kuhn len = curlen - pos; 11819af5a38SHeinrich Kuhn if (len > sizeof(tmpbuf)) 11919af5a38SHeinrich Kuhn len = sizeof(tmpbuf); 12019af5a38SHeinrich Kuhn 121030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: Receive %u of %zu", __func__, 12219af5a38SHeinrich Kuhn len, count); 12319af5a38SHeinrich Kuhn err = recv(sockfd, tmpbuf, len, MSG_WAITALL); 12419af5a38SHeinrich Kuhn if (err != (int)len) { 125f4d24fe9SChaoyong He PMD_CPP_LOG(ERR, "error when receiving, %d of %zu", 12654fdb550SChaoyong He err, count); 12719af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 12819af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 12919af5a38SHeinrich Kuhn return -EIO; 13019af5a38SHeinrich Kuhn } 131b0c496abSChaoyong He 13219af5a38SHeinrich Kuhn err = nfp_cpp_area_write(area, pos, tmpbuf, len); 13319af5a38SHeinrich Kuhn if (err < 0) { 13454fdb550SChaoyong He PMD_CPP_LOG(ERR, "nfp_cpp_area_write error"); 13519af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 13619af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 13719af5a38SHeinrich Kuhn return -EIO; 13819af5a38SHeinrich Kuhn } 13919af5a38SHeinrich Kuhn } 14019af5a38SHeinrich Kuhn 14119af5a38SHeinrich Kuhn nfp_offset += pos; 14219af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 14319af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 14419af5a38SHeinrich Kuhn 14519af5a38SHeinrich Kuhn count -= pos; 14619af5a38SHeinrich Kuhn curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? 14719af5a38SHeinrich Kuhn NFP_CPP_MEMIO_BOUNDARY : count; 14819af5a38SHeinrich Kuhn } 14919af5a38SHeinrich Kuhn 15019af5a38SHeinrich Kuhn return 0; 15119af5a38SHeinrich Kuhn } 15219af5a38SHeinrich Kuhn 15319af5a38SHeinrich Kuhn /* 15419af5a38SHeinrich Kuhn * Serving a read request to NFP from host programs. The request 15519af5a38SHeinrich Kuhn * sends the read size and the CPP target. The bridge makes use 15619af5a38SHeinrich Kuhn * of CPP interface handler configured by the PMD setup. The read 15719af5a38SHeinrich Kuhn * data is sent to the requester using the same socket. 15819af5a38SHeinrich Kuhn */ 15919af5a38SHeinrich Kuhn static int 160f4d24fe9SChaoyong He nfp_cpp_bridge_serve_read(int sockfd, 161f4d24fe9SChaoyong He struct nfp_cpp *cpp) 16219af5a38SHeinrich Kuhn { 16349952141SChaoyong He int err; 16449952141SChaoyong He off_t offset; 16549952141SChaoyong He uint32_t pos; 16649952141SChaoyong He uint32_t len; 16749952141SChaoyong He size_t count; 16849952141SChaoyong He size_t curlen; 16949952141SChaoyong He uint32_t cpp_id; 17049952141SChaoyong He off_t nfp_offset; 17119af5a38SHeinrich Kuhn uint32_t tmpbuf[16]; 17249952141SChaoyong He struct nfp_cpp_area *area; 17319af5a38SHeinrich Kuhn 174030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu", __func__, 17519af5a38SHeinrich Kuhn sizeof(off_t), sizeof(size_t)); 17619af5a38SHeinrich Kuhn 17719af5a38SHeinrich Kuhn /* Reading the count param */ 17819af5a38SHeinrich Kuhn err = recv(sockfd, &count, sizeof(off_t), 0); 17919af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 18019af5a38SHeinrich Kuhn return -EINVAL; 18119af5a38SHeinrich Kuhn 18219af5a38SHeinrich Kuhn curlen = count; 18319af5a38SHeinrich Kuhn 18419af5a38SHeinrich Kuhn /* Reading the offset param */ 18519af5a38SHeinrich Kuhn err = recv(sockfd, &offset, sizeof(off_t), 0); 18619af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 18719af5a38SHeinrich Kuhn return -EINVAL; 18819af5a38SHeinrich Kuhn 18919af5a38SHeinrich Kuhn /* Obtain target's CPP ID and offset in target */ 19019af5a38SHeinrich Kuhn cpp_id = (offset >> 40) << 8; 19119af5a38SHeinrich Kuhn nfp_offset = offset & ((1ull << 40) - 1); 19219af5a38SHeinrich Kuhn 193030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd", __func__, count, 19419af5a38SHeinrich Kuhn offset); 195030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd", __func__, 19619af5a38SHeinrich Kuhn cpp_id, nfp_offset); 19719af5a38SHeinrich Kuhn 19819af5a38SHeinrich Kuhn /* Adjust length if not aligned */ 19919af5a38SHeinrich Kuhn if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != 20019af5a38SHeinrich Kuhn (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { 20119af5a38SHeinrich Kuhn curlen = NFP_CPP_MEMIO_BOUNDARY - 20219af5a38SHeinrich Kuhn (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); 20319af5a38SHeinrich Kuhn } 20419af5a38SHeinrich Kuhn 20519af5a38SHeinrich Kuhn while (count > 0) { 20619af5a38SHeinrich Kuhn area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", 20719af5a38SHeinrich Kuhn nfp_offset, curlen); 208cbcbfd73SJames Hershaw if (area == NULL) { 20954fdb550SChaoyong He PMD_CPP_LOG(ERR, "area alloc failed"); 21019af5a38SHeinrich Kuhn return -EIO; 21119af5a38SHeinrich Kuhn } 21219af5a38SHeinrich Kuhn 21319af5a38SHeinrich Kuhn err = nfp_cpp_area_acquire(area); 21419af5a38SHeinrich Kuhn if (err < 0) { 21554fdb550SChaoyong He PMD_CPP_LOG(ERR, "area acquire failed"); 21619af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 21719af5a38SHeinrich Kuhn return -EIO; 21819af5a38SHeinrich Kuhn } 21919af5a38SHeinrich Kuhn 22019af5a38SHeinrich Kuhn for (pos = 0; pos < curlen; pos += len) { 22119af5a38SHeinrich Kuhn len = curlen - pos; 22219af5a38SHeinrich Kuhn if (len > sizeof(tmpbuf)) 22319af5a38SHeinrich Kuhn len = sizeof(tmpbuf); 22419af5a38SHeinrich Kuhn 22519af5a38SHeinrich Kuhn err = nfp_cpp_area_read(area, pos, tmpbuf, len); 22619af5a38SHeinrich Kuhn if (err < 0) { 22754fdb550SChaoyong He PMD_CPP_LOG(ERR, "nfp_cpp_area_read error"); 22819af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 22919af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 23019af5a38SHeinrich Kuhn return -EIO; 23119af5a38SHeinrich Kuhn } 232030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: sending %u of %zu", __func__, 23319af5a38SHeinrich Kuhn len, count); 23419af5a38SHeinrich Kuhn 23519af5a38SHeinrich Kuhn err = send(sockfd, tmpbuf, len, 0); 23619af5a38SHeinrich Kuhn if (err != (int)len) { 237f4d24fe9SChaoyong He PMD_CPP_LOG(ERR, "error when sending: %d of %zu", 23854fdb550SChaoyong He err, count); 23919af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 24019af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 24119af5a38SHeinrich Kuhn return -EIO; 24219af5a38SHeinrich Kuhn } 24319af5a38SHeinrich Kuhn } 24419af5a38SHeinrich Kuhn 24519af5a38SHeinrich Kuhn nfp_offset += pos; 24619af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 24719af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 24819af5a38SHeinrich Kuhn 24919af5a38SHeinrich Kuhn count -= pos; 25019af5a38SHeinrich Kuhn curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? 25119af5a38SHeinrich Kuhn NFP_CPP_MEMIO_BOUNDARY : count; 25219af5a38SHeinrich Kuhn } 253b0c496abSChaoyong He 25419af5a38SHeinrich Kuhn return 0; 25519af5a38SHeinrich Kuhn } 25619af5a38SHeinrich Kuhn 25719af5a38SHeinrich Kuhn /* 25819af5a38SHeinrich Kuhn * Serving a ioctl command from host NFP tools. This usually goes to 25919af5a38SHeinrich Kuhn * a kernel driver char driver but it is not available when the PF is 26019af5a38SHeinrich Kuhn * bound to the PMD. Currently just one ioctl command is served and it 26119af5a38SHeinrich Kuhn * does not require any CPP access at all. 26219af5a38SHeinrich Kuhn */ 26319af5a38SHeinrich Kuhn static int 264f4d24fe9SChaoyong He nfp_cpp_bridge_serve_ioctl(int sockfd, 265f4d24fe9SChaoyong He struct nfp_cpp *cpp) 26619af5a38SHeinrich Kuhn { 26719af5a38SHeinrich Kuhn int err; 26849952141SChaoyong He uint32_t cmd; 26949952141SChaoyong He uint32_t tmp; 27049952141SChaoyong He uint32_t ident_size; 27119af5a38SHeinrich Kuhn 27219af5a38SHeinrich Kuhn /* Reading now the IOCTL command */ 27319af5a38SHeinrich Kuhn err = recv(sockfd, &cmd, 4, 0); 27419af5a38SHeinrich Kuhn if (err != 4) { 27554fdb550SChaoyong He PMD_CPP_LOG(ERR, "read error from socket"); 27619af5a38SHeinrich Kuhn return -EIO; 27719af5a38SHeinrich Kuhn } 27819af5a38SHeinrich Kuhn 27919af5a38SHeinrich Kuhn /* Only supporting NFP_IOCTL_CPP_IDENTIFICATION */ 28019af5a38SHeinrich Kuhn if (cmd != NFP_IOCTL_CPP_IDENTIFICATION) { 28154fdb550SChaoyong He PMD_CPP_LOG(ERR, "unknown cmd %d", cmd); 28219af5a38SHeinrich Kuhn return -EINVAL; 28319af5a38SHeinrich Kuhn } 28419af5a38SHeinrich Kuhn 28519af5a38SHeinrich Kuhn err = recv(sockfd, &ident_size, 4, 0); 28619af5a38SHeinrich Kuhn if (err != 4) { 28754fdb550SChaoyong He PMD_CPP_LOG(ERR, "read error from socket"); 28819af5a38SHeinrich Kuhn return -EIO; 28919af5a38SHeinrich Kuhn } 29019af5a38SHeinrich Kuhn 29119af5a38SHeinrich Kuhn tmp = nfp_cpp_model(cpp); 29219af5a38SHeinrich Kuhn 293030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: sending NFP model %08x", __func__, tmp); 29419af5a38SHeinrich Kuhn 29519af5a38SHeinrich Kuhn err = send(sockfd, &tmp, 4, 0); 29619af5a38SHeinrich Kuhn if (err != 4) { 29754fdb550SChaoyong He PMD_CPP_LOG(ERR, "error writing to socket"); 29819af5a38SHeinrich Kuhn return -EIO; 29919af5a38SHeinrich Kuhn } 30019af5a38SHeinrich Kuhn 301ff627b74SChaoyong He tmp = nfp_cpp_interface(cpp); 30219af5a38SHeinrich Kuhn 303030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: sending NFP interface %08x", __func__, tmp); 30419af5a38SHeinrich Kuhn 30519af5a38SHeinrich Kuhn err = send(sockfd, &tmp, 4, 0); 30619af5a38SHeinrich Kuhn if (err != 4) { 30754fdb550SChaoyong He PMD_CPP_LOG(ERR, "error writing to socket"); 30819af5a38SHeinrich Kuhn return -EIO; 30919af5a38SHeinrich Kuhn } 31019af5a38SHeinrich Kuhn 31119af5a38SHeinrich Kuhn return 0; 31219af5a38SHeinrich Kuhn } 31319af5a38SHeinrich Kuhn 31419af5a38SHeinrich Kuhn /* 31519af5a38SHeinrich Kuhn * This is the code to be executed by a service core. The CPP bridge interface 31619af5a38SHeinrich Kuhn * is based on a unix socket and requests usually received by a kernel char 31719af5a38SHeinrich Kuhn * driver, read, write and ioctl, are handled by the CPP bridge. NFP host tools 31819af5a38SHeinrich Kuhn * can be executed with a wrapper library and LD_LIBRARY being completely 31919af5a38SHeinrich Kuhn * unaware of the CPP bridge performing the NFP kernel char driver for CPP 32019af5a38SHeinrich Kuhn * accesses. 32119af5a38SHeinrich Kuhn */ 322b1880421SChaoyong He static int 32319af5a38SHeinrich Kuhn nfp_cpp_bridge_service_func(void *args) 32419af5a38SHeinrich Kuhn { 32549952141SChaoyong He int op; 32649952141SChaoyong He int ret; 32749952141SChaoyong He int sockfd; 32849952141SChaoyong He int datafd; 329bab0e6f4SChaoyong He struct nfp_cpp *cpp; 330*600f6d2cSLong Wu const char *pci_name; 331*600f6d2cSLong Wu char socket_handle[14]; 33249952141SChaoyong He struct sockaddr address; 333bab0e6f4SChaoyong He struct nfp_pf_dev *pf_dev; 334a5b876a5SChaoyong He struct timeval timeout = {1, 0}; 33519af5a38SHeinrich Kuhn 336*600f6d2cSLong Wu pf_dev = args; 337b0c496abSChaoyong He 338*600f6d2cSLong Wu pci_name = strchr(pf_dev->pci_dev->name, ':') + 1; 339*600f6d2cSLong Wu snprintf(socket_handle, sizeof(socket_handle), "/tmp/%s", pci_name); 340*600f6d2cSLong Wu 341*600f6d2cSLong Wu unlink(socket_handle); 34219af5a38SHeinrich Kuhn sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 34319af5a38SHeinrich Kuhn if (sockfd < 0) { 34454fdb550SChaoyong He PMD_CPP_LOG(ERR, "socket creation error. Service failed"); 34519af5a38SHeinrich Kuhn return -EIO; 34619af5a38SHeinrich Kuhn } 34719af5a38SHeinrich Kuhn 348a5b876a5SChaoyong He setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); 349a5b876a5SChaoyong He 35019af5a38SHeinrich Kuhn memset(&address, 0, sizeof(struct sockaddr)); 35119af5a38SHeinrich Kuhn 35219af5a38SHeinrich Kuhn address.sa_family = AF_UNIX; 353*600f6d2cSLong Wu strcpy(address.sa_data, socket_handle); 35419af5a38SHeinrich Kuhn 35519af5a38SHeinrich Kuhn ret = bind(sockfd, (const struct sockaddr *)&address, 35619af5a38SHeinrich Kuhn sizeof(struct sockaddr)); 35719af5a38SHeinrich Kuhn if (ret < 0) { 35854fdb550SChaoyong He PMD_CPP_LOG(ERR, "bind error (%d). Service failed", errno); 35919af5a38SHeinrich Kuhn close(sockfd); 36019af5a38SHeinrich Kuhn return ret; 36119af5a38SHeinrich Kuhn } 36219af5a38SHeinrich Kuhn 36319af5a38SHeinrich Kuhn ret = listen(sockfd, 20); 36419af5a38SHeinrich Kuhn if (ret < 0) { 36554fdb550SChaoyong He PMD_CPP_LOG(ERR, "listen error(%d). Service failed", errno); 36619af5a38SHeinrich Kuhn close(sockfd); 36719af5a38SHeinrich Kuhn return ret; 36819af5a38SHeinrich Kuhn } 36919af5a38SHeinrich Kuhn 370bab0e6f4SChaoyong He cpp = pf_dev->cpp; 371*600f6d2cSLong Wu while (rte_service_runstate_get(pf_dev->cpp_service_info.id) != 0) { 37219af5a38SHeinrich Kuhn datafd = accept(sockfd, NULL, NULL); 37319af5a38SHeinrich Kuhn if (datafd < 0) { 374a5b876a5SChaoyong He if (errno == EAGAIN || errno == EWOULDBLOCK) 375a5b876a5SChaoyong He continue; 376a5b876a5SChaoyong He 37754fdb550SChaoyong He PMD_CPP_LOG(ERR, "accept call error (%d)", errno); 37854fdb550SChaoyong He PMD_CPP_LOG(ERR, "service failed"); 37919af5a38SHeinrich Kuhn close(sockfd); 38019af5a38SHeinrich Kuhn return -EIO; 38119af5a38SHeinrich Kuhn } 38219af5a38SHeinrich Kuhn 383e7978635SChaoyong He for (;;) { 38419af5a38SHeinrich Kuhn ret = recv(datafd, &op, 4, 0); 38519af5a38SHeinrich Kuhn if (ret <= 0) { 386030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: socket close", __func__); 38719af5a38SHeinrich Kuhn break; 38819af5a38SHeinrich Kuhn } 38919af5a38SHeinrich Kuhn 390030b2b19SChaoyong He PMD_CPP_LOG(DEBUG, "%s: getting op %u", __func__, op); 39119af5a38SHeinrich Kuhn 39219af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_READ) 39319af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_read(datafd, cpp); 39419af5a38SHeinrich Kuhn 39519af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_WRITE) 39619af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_write(datafd, cpp); 39719af5a38SHeinrich Kuhn 39819af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_IOCTL) 39919af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_ioctl(datafd, cpp); 40019af5a38SHeinrich Kuhn 40119af5a38SHeinrich Kuhn if (op == 0) 40219af5a38SHeinrich Kuhn break; 40319af5a38SHeinrich Kuhn } 404b0c496abSChaoyong He 40519af5a38SHeinrich Kuhn close(datafd); 40619af5a38SHeinrich Kuhn } 407b0c496abSChaoyong He 40819af5a38SHeinrich Kuhn close(sockfd); 40919af5a38SHeinrich Kuhn 41019af5a38SHeinrich Kuhn return 0; 41119af5a38SHeinrich Kuhn } 412