diff options
Diffstat (limited to 'host/lib/transport/uhd-dpdk')
-rw-r--r-- | host/lib/transport/uhd-dpdk/uhd_dpdk.c | 10 | ||||
-rw-r--r-- | host/lib/transport/uhd-dpdk/uhd_dpdk_ctx.h | 9 | ||||
-rw-r--r-- | host/lib/transport/uhd-dpdk/uhd_dpdk_driver.c | 53 | ||||
-rw-r--r-- | host/lib/transport/uhd-dpdk/uhd_dpdk_fops.c | 6 |
4 files changed, 73 insertions, 5 deletions
diff --git a/host/lib/transport/uhd-dpdk/uhd_dpdk.c b/host/lib/transport/uhd-dpdk/uhd_dpdk.c index 2ee74a201..d6a8a5aa6 100644 --- a/host/lib/transport/uhd-dpdk/uhd_dpdk.c +++ b/host/lib/transport/uhd-dpdk/uhd_dpdk.c @@ -87,6 +87,12 @@ static inline int uhd_dpdk_port_init(struct uhd_dpdk_port *port, return -ENODEV; /* Set up Ethernet device with defaults (1 RX ring, 1 TX ring) */ + retval = rte_eth_dev_set_mtu(port->id, mtu); + if (retval) { + RTE_LOG(WARNING, EAL, "%d: Could not set mtu to %d\n", retval, mtu); + rte_eth_dev_get_mtu(port->id, &mtu); + RTE_LOG(WARNING, EAL, "Current mtu=%d\n", mtu); + } /* FIXME: Check if hw_ip_checksum is possible */ struct rte_eth_conf port_conf = { .rxmode = { @@ -194,7 +200,7 @@ static int uhd_dpdk_thread_init(struct uhd_dpdk_thread *thread, unsigned int id) } -int uhd_dpdk_init(int argc, char **argv, unsigned int num_ports, +int uhd_dpdk_init(int argc, const char **argv, unsigned int num_ports, int *port_thread_mapping, int num_mbufs, int mbuf_cache_size, int mtu) { @@ -207,7 +213,7 @@ int uhd_dpdk_init(int argc, char **argv, unsigned int num_ports, } /* Grabs arguments intended for DPDK's EAL */ - int ret = rte_eal_init(argc, argv); + int ret = rte_eal_init(argc, (char **) argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); diff --git a/host/lib/transport/uhd-dpdk/uhd_dpdk_ctx.h b/host/lib/transport/uhd-dpdk/uhd_dpdk_ctx.h index 31c9dba0c..c6afab85d 100644 --- a/host/lib/transport/uhd-dpdk/uhd_dpdk_ctx.h +++ b/host/lib/transport/uhd-dpdk/uhd_dpdk_ctx.h @@ -106,6 +106,15 @@ struct uhd_dpdk_ipv4_5tuple { uint16_t dst_port; }; +/** + * Used for blocking calls to RX + */ +struct uhd_dpdk_sock_cond { + struct uhd_dpdk_socket *sock; + pthread_cond_t cond; + pthread_mutex_t mutex; +}; + /************************************************ * TX Queues * diff --git a/host/lib/transport/uhd-dpdk/uhd_dpdk_driver.c b/host/lib/transport/uhd-dpdk/uhd_dpdk_driver.c index 0af9cc4e5..8388359e7 100644 --- a/host/lib/transport/uhd-dpdk/uhd_dpdk_driver.c +++ b/host/lib/transport/uhd-dpdk/uhd_dpdk_driver.c @@ -11,11 +11,53 @@ #include <arpa/inet.h> #include <unistd.h> +int _uhd_dpdk_arp_reply(struct uhd_dpdk_port *port, struct arp_hdr *arp_req) +{ + struct rte_mbuf *mbuf; + struct ether_hdr *hdr; + struct arp_hdr *arp_frame; + + mbuf = rte_pktmbuf_alloc(port->parent->tx_pktbuf_pool); + if (unlikely(mbuf == NULL)) { + RTE_LOG(WARNING, MEMPOOL, "Could not allocate packet buffer for ARP response\n"); + return -ENOMEM; + } + + hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *); + arp_frame = (struct arp_hdr *) &hdr[1]; + + ether_addr_copy(&arp_req->arp_data.arp_sha, &hdr->d_addr); + ether_addr_copy(&port->mac_addr, &hdr->s_addr); + hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_ARP); + + arp_frame->arp_hrd = rte_cpu_to_be_16(ARP_HRD_ETHER); + arp_frame->arp_pro = rte_cpu_to_be_16(ETHER_TYPE_IPv4); + arp_frame->arp_hln = 6; + arp_frame->arp_pln = 4; + arp_frame->arp_op = rte_cpu_to_be_16(ARP_OP_REPLY); + ether_addr_copy(&port->mac_addr, &arp_frame->arp_data.arp_sha); + arp_frame->arp_data.arp_sip = port->ipv4_addr; + ether_addr_copy(&hdr->d_addr, &arp_frame->arp_data.arp_tha); + arp_frame->arp_data.arp_tip = arp_req->arp_data.arp_sip; + + mbuf->pkt_len = 42; + mbuf->data_len = 42; + mbuf->ol_flags = PKT_TX_IP_CKSUM; + + if (rte_eth_tx_burst(port->id, 0, &mbuf, 1) != 1) { + RTE_LOG(WARNING, RING, "%s: TX descriptor ring is full\n", __func__); + rte_pktmbuf_free(mbuf); + return -EAGAIN; + } + return 0; +} + int _uhd_dpdk_process_arp(struct uhd_dpdk_port *port, struct arp_hdr *arp_frame) { uint32_t dest_ip = arp_frame->arp_data.arp_sip; struct ether_addr dest_addr = arp_frame->arp_data.arp_sha; + /* Add entry to ARP table */ struct uhd_dpdk_arp_entry *entry = NULL; rte_hash_lookup_data(port->arp_table, &dest_ip, (void **) &entry); if (!entry) { @@ -36,11 +78,21 @@ int _uhd_dpdk_process_arp(struct uhd_dpdk_port *port, struct arp_hdr *arp_frame) LIST_FOREACH(req, &entry->pending_list, entry) { _uhd_dpdk_config_req_compl(req, 0); } + while (entry->pending_list.lh_first != NULL) { + LIST_REMOVE(entry->pending_list.lh_first, entry); + } + } + + /* Respond if this was an ARP request */ + if (arp_frame->arp_op == rte_cpu_to_be_16(ARP_OP_REQUEST) && + arp_frame->arp_data.arp_tip == port->ipv4_addr) { + _uhd_dpdk_arp_reply(port, arp_frame); } return 0; } +/* Send ARP request */ int _uhd_dpdk_arp_request(struct uhd_dpdk_port *port, uint32_t ip) { struct rte_mbuf *mbuf; @@ -82,7 +134,6 @@ int _uhd_dpdk_arp_request(struct uhd_dpdk_port *port, uint32_t ip) return 0; } - int _uhd_dpdk_process_udp(struct uhd_dpdk_port *port, struct rte_mbuf *mbuf, struct udp_hdr *pkt) { int status = 0; diff --git a/host/lib/transport/uhd-dpdk/uhd_dpdk_fops.c b/host/lib/transport/uhd-dpdk/uhd_dpdk_fops.c index 3acc3d709..309e5e643 100644 --- a/host/lib/transport/uhd-dpdk/uhd_dpdk_fops.c +++ b/host/lib/transport/uhd-dpdk/uhd_dpdk_fops.c @@ -215,7 +215,7 @@ int uhd_dpdk_send(struct uhd_dpdk_socket *sock, struct rte_mbuf **bufs, * Add blocking calls with timeout */ int uhd_dpdk_recv(struct uhd_dpdk_socket *sock, struct rte_mbuf **bufs, - unsigned int num_bufs, unsigned int timeout) + unsigned int num_bufs, int timeout) { if (!sock || !bufs || !num_bufs) return -EINVAL; @@ -223,7 +223,9 @@ int uhd_dpdk_recv(struct uhd_dpdk_socket *sock, struct rte_mbuf **bufs, return -EINVAL; unsigned int num_rx = rte_ring_count(sock->rx_ring); num_rx = (num_rx < num_bufs) ? num_rx : num_bufs; - if (num_rx) { + /* if ((timeout > 0) && (num_rx != num_bufs)) { + // Wait for enough bufs + } else*/ if (num_rx) { unsigned int avail = 0; unsigned int status = rte_ring_dequeue_bulk(sock->rx_ring, (void **) bufs, num_rx, &avail); |