#include <linux/kthread.h>
#include <linux/delay.h>
-#include <rte_config.h>
#include <exec-env/rte_kni_common.h>
#include <kni_fifo.h>
#include "kni_dev.h"
struct rte_kni_request req;
struct kni_dev *kni = netdev_priv(dev);
- if (kni->lad_dev)
- memcpy(dev->dev_addr, kni->lad_dev->dev_addr, ETH_ALEN);
- else
- /*
- * Generate random mac address. eth_random_addr() is the newer
- * version of generating mac address in linux kernel.
- */
- random_ether_addr(dev->dev_addr);
-
netif_start_queue(dev);
memset(&req, 0, sizeof(req));
/* Transfer received packets to netif */
for (i = 0; i < num_rx; i++) {
kva = (void *)va[i] - kni->mbuf_va + kni->mbuf_kva;
- len = kva->data_len;
+ len = kva->pkt_len;
+
data_kva = kva->buf_addr + kva->data_off - kni->mbuf_va
+ kni->mbuf_kva;
KNI_ERR("Out of mem, dropping pkts\n");
/* Update statistics */
kni->stats.rx_dropped++;
+ continue;
}
- else {
- /* Align IP on 16B boundary */
- skb_reserve(skb, 2);
+
+ /* Align IP on 16B boundary */
+ skb_reserve(skb, 2);
+
+ if (kva->nb_segs == 1) {
memcpy(skb_put(skb, len), data_kva, len);
- skb->dev = dev;
- skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ int nb_segs;
+ int kva_nb_segs = kva->nb_segs;
- /* Call netif interface */
- netif_rx(skb);
+ for (nb_segs = 0; nb_segs < kva_nb_segs; nb_segs++) {
+ memcpy(skb_put(skb, kva->data_len),
+ data_kva, kva->data_len);
- /* Update statistics */
- kni->stats.rx_bytes += len;
- kni->stats.rx_packets++;
+ if (!kva->next)
+ break;
+
+ kva = kva->next - kni->mbuf_va + kni->mbuf_kva;
+ data_kva = kva->buf_addr + kva->data_off
+ - kni->mbuf_va + kni->mbuf_kva;
+ }
}
+
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ /* Call netif interface */
+ netif_rx_ni(skb);
+
+ /* Update statistics */
+ kni->stats.rx_bytes += len;
+ kni->stats.rx_packets++;
}
/* Burst enqueue mbufs into free_q */
/* Copy mbufs to sk buffer and then call tx interface */
for (i = 0; i < num; i++) {
kva = (void *)va[i] - kni->mbuf_va + kni->mbuf_kva;
- len = kva->data_len;
+ len = kva->pkt_len;
data_kva = kva->buf_addr + kva->data_off - kni->mbuf_va +
kni->mbuf_kva;
if (skb == NULL) {
KNI_ERR("Out of mem, dropping pkts\n");
kni->stats.rx_dropped++;
+ continue;
}
- else {
- /* Align IP on 16B boundary */
- skb_reserve(skb, 2);
+
+ /* Align IP on 16B boundary */
+ skb_reserve(skb, 2);
+
+ if (kva->nb_segs == 1) {
memcpy(skb_put(skb, len), data_kva, len);
- skb->dev = dev;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else {
+ int nb_segs;
+ int kva_nb_segs = kva->nb_segs;
- kni->stats.rx_bytes += len;
- kni->stats.rx_packets++;
+ for (nb_segs = 0; nb_segs < kva_nb_segs; nb_segs++) {
+ memcpy(skb_put(skb, kva->data_len),
+ data_kva, kva->data_len);
+
+ if (!kva->next)
+ break;
- /* call tx interface */
- kni_net_tx(skb, dev);
+ kva = kva->next - kni->mbuf_va + kni->mbuf_kva;
+ data_kva = kva->buf_addr + kva->data_off
+ - kni->mbuf_va + kni->mbuf_kva;
+ }
}
+
+ skb->dev = dev;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ kni->stats.rx_bytes += len;
+ kni->stats.rx_packets++;
+
+ /* call tx interface */
+ kni_net_tx(skb, dev);
}
/* enqueue all the mbufs from rx_q into free_q */
/*
* Re-fill the eth header
*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0))
static int
kni_net_rebuild_header(struct sk_buff *skb)
{
return 0;
}
+#endif /* < 4.1.0 */
/**
* kni_net_set_mac - Change the Ethernet Address of the KNI NIC
static const struct header_ops kni_net_header_ops = {
.create = kni_net_header,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0))
.rebuild = kni_net_rebuild_header,
+#endif /* < 4.1.0 */
.cache = NULL, /* disable caching */
};