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" 13600f6d2cSLong 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; 30600f6d2cSLong Wu const char *pci_name; 31b1880421SChaoyong He struct rte_service_spec cpp_service = { 32b1880421SChaoyong He .callback = nfp_cpp_bridge_service_func, 33600f6d2cSLong Wu .callback_userdata = (void *)pf_dev, 34b1880421SChaoyong He }; 35b1880421SChaoyong He 36600f6d2cSLong Wu pci_name = strchr(pf_dev->pci_dev->name, ':') + 1; 37600f6d2cSLong Wu snprintf(cpp_service.name, sizeof(cpp_service.name), "%s_cpp_service", pci_name); 38b1880421SChaoyong He 39600f6d2cSLong Wu ret = nfp_service_enable(&cpp_service, &pf_dev->cpp_service_info); 40b1880421SChaoyong He if (ret != 0) { 41*b6de4353SZerun Fu PMD_INIT_LOG(DEBUG, "Could not enable service %s.", cpp_service.name); 42600f6d2cSLong Wu return ret; 43b1880421SChaoyong He } 44b1880421SChaoyong He 45b1880421SChaoyong He return 0; 4619af5a38SHeinrich Kuhn } 4719af5a38SHeinrich Kuhn 48929b0531SLong Wu void 49929b0531SLong Wu nfp_disable_cpp_service(struct nfp_pf_dev *pf_dev) 50929b0531SLong Wu { 51929b0531SLong Wu nfp_service_disable(&pf_dev->cpp_service_info); 52929b0531SLong Wu } 53929b0531SLong Wu 5419af5a38SHeinrich Kuhn /* 5519af5a38SHeinrich Kuhn * Serving a write request to NFP from host programs. The request 5619af5a38SHeinrich Kuhn * sends the write size and the CPP target. The bridge makes use 5719af5a38SHeinrich Kuhn * of CPP interface handler configured by the PMD setup. 5819af5a38SHeinrich Kuhn */ 5919af5a38SHeinrich Kuhn static int 60f4d24fe9SChaoyong He nfp_cpp_bridge_serve_write(int sockfd, 61f4d24fe9SChaoyong He struct nfp_cpp *cpp) 6219af5a38SHeinrich Kuhn { 6349952141SChaoyong He int err; 6449952141SChaoyong He off_t offset; 6549952141SChaoyong He uint32_t pos; 6649952141SChaoyong He uint32_t len; 6749952141SChaoyong He size_t count; 6849952141SChaoyong He size_t curlen; 6949952141SChaoyong He uint32_t cpp_id; 7049952141SChaoyong He off_t nfp_offset; 7119af5a38SHeinrich Kuhn uint32_t tmpbuf[16]; 7249952141SChaoyong He struct nfp_cpp_area *area; 7319af5a38SHeinrich Kuhn 74*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu.", __func__, 7519af5a38SHeinrich Kuhn sizeof(off_t), sizeof(size_t)); 7619af5a38SHeinrich Kuhn 7719af5a38SHeinrich Kuhn /* Reading the count param */ 7819af5a38SHeinrich Kuhn err = recv(sockfd, &count, sizeof(off_t), 0); 7919af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 8019af5a38SHeinrich Kuhn return -EINVAL; 8119af5a38SHeinrich Kuhn 8219af5a38SHeinrich Kuhn curlen = count; 8319af5a38SHeinrich Kuhn 8419af5a38SHeinrich Kuhn /* Reading the offset param */ 8519af5a38SHeinrich Kuhn err = recv(sockfd, &offset, sizeof(off_t), 0); 8619af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 8719af5a38SHeinrich Kuhn return -EINVAL; 8819af5a38SHeinrich Kuhn 8919af5a38SHeinrich Kuhn /* Obtain target's CPP ID and offset in target */ 9019af5a38SHeinrich Kuhn cpp_id = (offset >> 40) << 8; 9119af5a38SHeinrich Kuhn nfp_offset = offset & ((1ull << 40) - 1); 9219af5a38SHeinrich Kuhn 93*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd.", __func__, count, 9419af5a38SHeinrich Kuhn offset); 95*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd.", __func__, 9619af5a38SHeinrich Kuhn cpp_id, nfp_offset); 9719af5a38SHeinrich Kuhn 9819af5a38SHeinrich Kuhn /* Adjust length if not aligned */ 9919af5a38SHeinrich Kuhn if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != 10019af5a38SHeinrich Kuhn (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { 10119af5a38SHeinrich Kuhn curlen = NFP_CPP_MEMIO_BOUNDARY - 10219af5a38SHeinrich Kuhn (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); 10319af5a38SHeinrich Kuhn } 10419af5a38SHeinrich Kuhn 10519af5a38SHeinrich Kuhn while (count > 0) { 106030b2b19SChaoyong He /* Configure a CPP PCIe2CPP BAR for mapping the CPP target */ 10719af5a38SHeinrich Kuhn area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", 10819af5a38SHeinrich Kuhn nfp_offset, curlen); 109cbcbfd73SJames Hershaw if (area == NULL) { 110*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Area alloc fail."); 11119af5a38SHeinrich Kuhn return -EIO; 11219af5a38SHeinrich Kuhn } 11319af5a38SHeinrich Kuhn 114030b2b19SChaoyong He /* Mapping the target */ 11519af5a38SHeinrich Kuhn err = nfp_cpp_area_acquire(area); 11619af5a38SHeinrich Kuhn if (err < 0) { 117*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Area acquire failed."); 11819af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 11919af5a38SHeinrich Kuhn return -EIO; 12019af5a38SHeinrich Kuhn } 12119af5a38SHeinrich Kuhn 12219af5a38SHeinrich Kuhn for (pos = 0; pos < curlen; pos += len) { 12319af5a38SHeinrich Kuhn len = curlen - pos; 12419af5a38SHeinrich Kuhn if (len > sizeof(tmpbuf)) 12519af5a38SHeinrich Kuhn len = sizeof(tmpbuf); 12619af5a38SHeinrich Kuhn 127*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: Receive %u of %zu.", __func__, 12819af5a38SHeinrich Kuhn len, count); 12919af5a38SHeinrich Kuhn err = recv(sockfd, tmpbuf, len, MSG_WAITALL); 13019af5a38SHeinrich Kuhn if (err != (int)len) { 131*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Error when receiving, %d of %zu.", 13254fdb550SChaoyong He err, count); 13319af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 13419af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 13519af5a38SHeinrich Kuhn return -EIO; 13619af5a38SHeinrich Kuhn } 137b0c496abSChaoyong He 13819af5a38SHeinrich Kuhn err = nfp_cpp_area_write(area, pos, tmpbuf, len); 13919af5a38SHeinrich Kuhn if (err < 0) { 140*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "The nfp_cpp_area_write error."); 14119af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 14219af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 14319af5a38SHeinrich Kuhn return -EIO; 14419af5a38SHeinrich Kuhn } 14519af5a38SHeinrich Kuhn } 14619af5a38SHeinrich Kuhn 14719af5a38SHeinrich Kuhn nfp_offset += pos; 14819af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 14919af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 15019af5a38SHeinrich Kuhn 15119af5a38SHeinrich Kuhn count -= pos; 15219af5a38SHeinrich Kuhn curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? 15319af5a38SHeinrich Kuhn NFP_CPP_MEMIO_BOUNDARY : count; 15419af5a38SHeinrich Kuhn } 15519af5a38SHeinrich Kuhn 15619af5a38SHeinrich Kuhn return 0; 15719af5a38SHeinrich Kuhn } 15819af5a38SHeinrich Kuhn 15919af5a38SHeinrich Kuhn /* 16019af5a38SHeinrich Kuhn * Serving a read request to NFP from host programs. The request 16119af5a38SHeinrich Kuhn * sends the read size and the CPP target. The bridge makes use 16219af5a38SHeinrich Kuhn * of CPP interface handler configured by the PMD setup. The read 16319af5a38SHeinrich Kuhn * data is sent to the requester using the same socket. 16419af5a38SHeinrich Kuhn */ 16519af5a38SHeinrich Kuhn static int 166f4d24fe9SChaoyong He nfp_cpp_bridge_serve_read(int sockfd, 167f4d24fe9SChaoyong He struct nfp_cpp *cpp) 16819af5a38SHeinrich Kuhn { 16949952141SChaoyong He int err; 17049952141SChaoyong He off_t offset; 17149952141SChaoyong He uint32_t pos; 17249952141SChaoyong He uint32_t len; 17349952141SChaoyong He size_t count; 17449952141SChaoyong He size_t curlen; 17549952141SChaoyong He uint32_t cpp_id; 17649952141SChaoyong He off_t nfp_offset; 17719af5a38SHeinrich Kuhn uint32_t tmpbuf[16]; 17849952141SChaoyong He struct nfp_cpp_area *area; 17919af5a38SHeinrich Kuhn 180*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: offset size %zu, count_size: %zu.", __func__, 18119af5a38SHeinrich Kuhn sizeof(off_t), sizeof(size_t)); 18219af5a38SHeinrich Kuhn 18319af5a38SHeinrich Kuhn /* Reading the count param */ 18419af5a38SHeinrich Kuhn err = recv(sockfd, &count, sizeof(off_t), 0); 18519af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 18619af5a38SHeinrich Kuhn return -EINVAL; 18719af5a38SHeinrich Kuhn 18819af5a38SHeinrich Kuhn curlen = count; 18919af5a38SHeinrich Kuhn 19019af5a38SHeinrich Kuhn /* Reading the offset param */ 19119af5a38SHeinrich Kuhn err = recv(sockfd, &offset, sizeof(off_t), 0); 19219af5a38SHeinrich Kuhn if (err != sizeof(off_t)) 19319af5a38SHeinrich Kuhn return -EINVAL; 19419af5a38SHeinrich Kuhn 19519af5a38SHeinrich Kuhn /* Obtain target's CPP ID and offset in target */ 19619af5a38SHeinrich Kuhn cpp_id = (offset >> 40) << 8; 19719af5a38SHeinrich Kuhn nfp_offset = offset & ((1ull << 40) - 1); 19819af5a38SHeinrich Kuhn 199*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: count %zu and offset %jd.", __func__, count, 20019af5a38SHeinrich Kuhn offset); 201*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: cpp_id %08x and nfp_offset %jd.", __func__, 20219af5a38SHeinrich Kuhn cpp_id, nfp_offset); 20319af5a38SHeinrich Kuhn 20419af5a38SHeinrich Kuhn /* Adjust length if not aligned */ 20519af5a38SHeinrich Kuhn if (((nfp_offset + (off_t)count - 1) & ~(NFP_CPP_MEMIO_BOUNDARY - 1)) != 20619af5a38SHeinrich Kuhn (nfp_offset & ~(NFP_CPP_MEMIO_BOUNDARY - 1))) { 20719af5a38SHeinrich Kuhn curlen = NFP_CPP_MEMIO_BOUNDARY - 20819af5a38SHeinrich Kuhn (nfp_offset & (NFP_CPP_MEMIO_BOUNDARY - 1)); 20919af5a38SHeinrich Kuhn } 21019af5a38SHeinrich Kuhn 21119af5a38SHeinrich Kuhn while (count > 0) { 21219af5a38SHeinrich Kuhn area = nfp_cpp_area_alloc_with_name(cpp, cpp_id, "nfp.cdev", 21319af5a38SHeinrich Kuhn nfp_offset, curlen); 214cbcbfd73SJames Hershaw if (area == NULL) { 215*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Area alloc failed."); 21619af5a38SHeinrich Kuhn return -EIO; 21719af5a38SHeinrich Kuhn } 21819af5a38SHeinrich Kuhn 21919af5a38SHeinrich Kuhn err = nfp_cpp_area_acquire(area); 22019af5a38SHeinrich Kuhn if (err < 0) { 221*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Area acquire failed."); 22219af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 22319af5a38SHeinrich Kuhn return -EIO; 22419af5a38SHeinrich Kuhn } 22519af5a38SHeinrich Kuhn 22619af5a38SHeinrich Kuhn for (pos = 0; pos < curlen; pos += len) { 22719af5a38SHeinrich Kuhn len = curlen - pos; 22819af5a38SHeinrich Kuhn if (len > sizeof(tmpbuf)) 22919af5a38SHeinrich Kuhn len = sizeof(tmpbuf); 23019af5a38SHeinrich Kuhn 23119af5a38SHeinrich Kuhn err = nfp_cpp_area_read(area, pos, tmpbuf, len); 23219af5a38SHeinrich Kuhn if (err < 0) { 233*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "The nfp_cpp_area_read error."); 23419af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 23519af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 23619af5a38SHeinrich Kuhn return -EIO; 23719af5a38SHeinrich Kuhn } 238*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: sending %u of %zu.", __func__, 23919af5a38SHeinrich Kuhn len, count); 24019af5a38SHeinrich Kuhn 24119af5a38SHeinrich Kuhn err = send(sockfd, tmpbuf, len, 0); 24219af5a38SHeinrich Kuhn if (err != (int)len) { 243*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Error when sending: %d of %zu.", 24454fdb550SChaoyong He err, count); 24519af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 24619af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 24719af5a38SHeinrich Kuhn return -EIO; 24819af5a38SHeinrich Kuhn } 24919af5a38SHeinrich Kuhn } 25019af5a38SHeinrich Kuhn 25119af5a38SHeinrich Kuhn nfp_offset += pos; 25219af5a38SHeinrich Kuhn nfp_cpp_area_release(area); 25319af5a38SHeinrich Kuhn nfp_cpp_area_free(area); 25419af5a38SHeinrich Kuhn 25519af5a38SHeinrich Kuhn count -= pos; 25619af5a38SHeinrich Kuhn curlen = (count > NFP_CPP_MEMIO_BOUNDARY) ? 25719af5a38SHeinrich Kuhn NFP_CPP_MEMIO_BOUNDARY : count; 25819af5a38SHeinrich Kuhn } 259b0c496abSChaoyong He 26019af5a38SHeinrich Kuhn return 0; 26119af5a38SHeinrich Kuhn } 26219af5a38SHeinrich Kuhn 26319af5a38SHeinrich Kuhn /* 26419af5a38SHeinrich Kuhn * Serving a ioctl command from host NFP tools. This usually goes to 26519af5a38SHeinrich Kuhn * a kernel driver char driver but it is not available when the PF is 26619af5a38SHeinrich Kuhn * bound to the PMD. Currently just one ioctl command is served and it 26719af5a38SHeinrich Kuhn * does not require any CPP access at all. 26819af5a38SHeinrich Kuhn */ 26919af5a38SHeinrich Kuhn static int 270f4d24fe9SChaoyong He nfp_cpp_bridge_serve_ioctl(int sockfd, 271f4d24fe9SChaoyong He struct nfp_cpp *cpp) 27219af5a38SHeinrich Kuhn { 27319af5a38SHeinrich Kuhn int err; 27449952141SChaoyong He uint32_t cmd; 27549952141SChaoyong He uint32_t tmp; 27649952141SChaoyong He uint32_t ident_size; 27719af5a38SHeinrich Kuhn 27819af5a38SHeinrich Kuhn /* Reading now the IOCTL command */ 27919af5a38SHeinrich Kuhn err = recv(sockfd, &cmd, 4, 0); 28019af5a38SHeinrich Kuhn if (err != 4) { 281*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Read error from socket."); 28219af5a38SHeinrich Kuhn return -EIO; 28319af5a38SHeinrich Kuhn } 28419af5a38SHeinrich Kuhn 28519af5a38SHeinrich Kuhn /* Only supporting NFP_IOCTL_CPP_IDENTIFICATION */ 28619af5a38SHeinrich Kuhn if (cmd != NFP_IOCTL_CPP_IDENTIFICATION) { 287*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Unknown cmd %d.", cmd); 28819af5a38SHeinrich Kuhn return -EINVAL; 28919af5a38SHeinrich Kuhn } 29019af5a38SHeinrich Kuhn 29119af5a38SHeinrich Kuhn err = recv(sockfd, &ident_size, 4, 0); 29219af5a38SHeinrich Kuhn if (err != 4) { 293*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Read error from socket."); 29419af5a38SHeinrich Kuhn return -EIO; 29519af5a38SHeinrich Kuhn } 29619af5a38SHeinrich Kuhn 29719af5a38SHeinrich Kuhn tmp = nfp_cpp_model(cpp); 29819af5a38SHeinrich Kuhn 299*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: sending NFP model %08x.", __func__, tmp); 30019af5a38SHeinrich Kuhn 30119af5a38SHeinrich Kuhn err = send(sockfd, &tmp, 4, 0); 30219af5a38SHeinrich Kuhn if (err != 4) { 303*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Error writing to socket."); 30419af5a38SHeinrich Kuhn return -EIO; 30519af5a38SHeinrich Kuhn } 30619af5a38SHeinrich Kuhn 307ff627b74SChaoyong He tmp = nfp_cpp_interface(cpp); 30819af5a38SHeinrich Kuhn 309*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: sending NFP interface %08x.", __func__, tmp); 31019af5a38SHeinrich Kuhn 31119af5a38SHeinrich Kuhn err = send(sockfd, &tmp, 4, 0); 31219af5a38SHeinrich Kuhn if (err != 4) { 313*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Error writing to socket."); 31419af5a38SHeinrich Kuhn return -EIO; 31519af5a38SHeinrich Kuhn } 31619af5a38SHeinrich Kuhn 31719af5a38SHeinrich Kuhn return 0; 31819af5a38SHeinrich Kuhn } 31919af5a38SHeinrich Kuhn 32019af5a38SHeinrich Kuhn /* 32119af5a38SHeinrich Kuhn * This is the code to be executed by a service core. The CPP bridge interface 32219af5a38SHeinrich Kuhn * is based on a unix socket and requests usually received by a kernel char 32319af5a38SHeinrich Kuhn * driver, read, write and ioctl, are handled by the CPP bridge. NFP host tools 32419af5a38SHeinrich Kuhn * can be executed with a wrapper library and LD_LIBRARY being completely 32519af5a38SHeinrich Kuhn * unaware of the CPP bridge performing the NFP kernel char driver for CPP 32619af5a38SHeinrich Kuhn * accesses. 32719af5a38SHeinrich Kuhn */ 328b1880421SChaoyong He static int 32919af5a38SHeinrich Kuhn nfp_cpp_bridge_service_func(void *args) 33019af5a38SHeinrich Kuhn { 33149952141SChaoyong He int op; 33249952141SChaoyong He int ret; 33349952141SChaoyong He int sockfd; 33449952141SChaoyong He int datafd; 335bab0e6f4SChaoyong He struct nfp_cpp *cpp; 336600f6d2cSLong Wu const char *pci_name; 337600f6d2cSLong Wu char socket_handle[14]; 33849952141SChaoyong He struct sockaddr address; 339bab0e6f4SChaoyong He struct nfp_pf_dev *pf_dev; 340a5b876a5SChaoyong He struct timeval timeout = {1, 0}; 34119af5a38SHeinrich Kuhn 342600f6d2cSLong Wu pf_dev = args; 343b0c496abSChaoyong He 344600f6d2cSLong Wu pci_name = strchr(pf_dev->pci_dev->name, ':') + 1; 345600f6d2cSLong Wu snprintf(socket_handle, sizeof(socket_handle), "/tmp/%s", pci_name); 346600f6d2cSLong Wu 347600f6d2cSLong Wu unlink(socket_handle); 34819af5a38SHeinrich Kuhn sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 34919af5a38SHeinrich Kuhn if (sockfd < 0) { 350*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Socket creation error. Service failed."); 35119af5a38SHeinrich Kuhn return -EIO; 35219af5a38SHeinrich Kuhn } 35319af5a38SHeinrich Kuhn 354a5b876a5SChaoyong He setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)); 355a5b876a5SChaoyong He 35619af5a38SHeinrich Kuhn memset(&address, 0, sizeof(struct sockaddr)); 35719af5a38SHeinrich Kuhn 35819af5a38SHeinrich Kuhn address.sa_family = AF_UNIX; 359600f6d2cSLong Wu strcpy(address.sa_data, socket_handle); 36019af5a38SHeinrich Kuhn 36119af5a38SHeinrich Kuhn ret = bind(sockfd, (const struct sockaddr *)&address, 36219af5a38SHeinrich Kuhn sizeof(struct sockaddr)); 36319af5a38SHeinrich Kuhn if (ret < 0) { 364*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Bind error (%d). Service failed.", errno); 36519af5a38SHeinrich Kuhn close(sockfd); 36619af5a38SHeinrich Kuhn return ret; 36719af5a38SHeinrich Kuhn } 36819af5a38SHeinrich Kuhn 36919af5a38SHeinrich Kuhn ret = listen(sockfd, 20); 37019af5a38SHeinrich Kuhn if (ret < 0) { 371*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Listen error(%d). Service failed.", errno); 37219af5a38SHeinrich Kuhn close(sockfd); 37319af5a38SHeinrich Kuhn return ret; 37419af5a38SHeinrich Kuhn } 37519af5a38SHeinrich Kuhn 376bab0e6f4SChaoyong He cpp = pf_dev->cpp; 377600f6d2cSLong Wu while (rte_service_runstate_get(pf_dev->cpp_service_info.id) != 0) { 37819af5a38SHeinrich Kuhn datafd = accept(sockfd, NULL, NULL); 37919af5a38SHeinrich Kuhn if (datafd < 0) { 380a5b876a5SChaoyong He if (errno == EAGAIN || errno == EWOULDBLOCK) 381a5b876a5SChaoyong He continue; 382a5b876a5SChaoyong He 383*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Accept call error (%d).", errno); 384*b6de4353SZerun Fu PMD_CPP_LOG(ERR, "Service failed."); 38519af5a38SHeinrich Kuhn close(sockfd); 38619af5a38SHeinrich Kuhn return -EIO; 38719af5a38SHeinrich Kuhn } 38819af5a38SHeinrich Kuhn 389e7978635SChaoyong He for (;;) { 39019af5a38SHeinrich Kuhn ret = recv(datafd, &op, 4, 0); 39119af5a38SHeinrich Kuhn if (ret <= 0) { 392*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: socket close.", __func__); 39319af5a38SHeinrich Kuhn break; 39419af5a38SHeinrich Kuhn } 39519af5a38SHeinrich Kuhn 396*b6de4353SZerun Fu PMD_CPP_LOG(DEBUG, "%s: getting op %u.", __func__, op); 39719af5a38SHeinrich Kuhn 39819af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_READ) 39919af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_read(datafd, cpp); 40019af5a38SHeinrich Kuhn 40119af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_WRITE) 40219af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_write(datafd, cpp); 40319af5a38SHeinrich Kuhn 40419af5a38SHeinrich Kuhn if (op == NFP_BRIDGE_OP_IOCTL) 40519af5a38SHeinrich Kuhn nfp_cpp_bridge_serve_ioctl(datafd, cpp); 40619af5a38SHeinrich Kuhn 40719af5a38SHeinrich Kuhn if (op == 0) 40819af5a38SHeinrich Kuhn break; 40919af5a38SHeinrich Kuhn } 410b0c496abSChaoyong He 41119af5a38SHeinrich Kuhn close(datafd); 41219af5a38SHeinrich Kuhn } 413b0c496abSChaoyong He 41419af5a38SHeinrich Kuhn close(sockfd); 41519af5a38SHeinrich Kuhn 41619af5a38SHeinrich Kuhn return 0; 41719af5a38SHeinrich Kuhn } 418