aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport/uhd-dpdk
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport/uhd-dpdk')
-rw-r--r--host/lib/transport/uhd-dpdk/uhd_dpdk.c10
-rw-r--r--host/lib/transport/uhd-dpdk/uhd_dpdk_ctx.h9
-rw-r--r--host/lib/transport/uhd-dpdk/uhd_dpdk_driver.c53
-rw-r--r--host/lib/transport/uhd-dpdk/uhd_dpdk_fops.c6
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);