On 28/01/16 07:03, Matias Elo wrote:
+static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
+ odp_packet_t pkt_table[],
+ struct rte_mbuf *mbuf_table[],
+ uint16_t num)
{
- return 0;
+ odp_packet_t pkt;
+ int i;
+ odp_packet_hdr_t *pkt_hdr;
+ uint16_t pkt_len;
+ void *buf;
+
+ for (i = 0; i < num; i++) {
+ buf = rte_pktmbuf_mtod(mbuf_table[i], char *);
+ odp_prefetch(buf);
+
+ pkt_len = rte_pktmbuf_pkt_len(mbuf_table[i]);
+
+ pkt = packet_alloc(pktio_entry->s.pkt_dpdk.pool, pkt_len, 1);
+ if (pkt == ODP_PACKET_INVALID) {
+ ODP_ERR("packet_alloc failed\n");
+ goto fail;
+ }
+
+ pkt_hdr = odp_packet_hdr(pkt);
+
+ /* For now copy the data in the mbuf,
+ worry about zero-copy later */
+ if (odp_packet_copydata_in(pkt, 0, pkt_len, buf) != 0) {
I think this doesn't work if someone sets the MTU higher than your mbuf
size. Although ODP doesn't support that now, you should at least assert
that nb_segs == 1, and abort if it's not true.
Also, the RSS hash is worth to copy so you don't have to calculate it in sw.
+ ODP_ERR("odp_packet_copydata_in failed\n");
+ odp_packet_free(pkt);
+ goto fail;
+ }
+
+ packet_parse_l2(pkt_hdr);
+
+ pkt_hdr->input = pktio_entry->s.handle;
+
+ pkt_table[i] = pkt;
+
+ rte_pktmbuf_free(mbuf_table[i]);
+ }
+
+ return i;
+
+fail:
+ ODP_ERR("Creating ODP packet failed\n");
+ rte_pktmbuf_free(mbuf_table[i]);
+ return (i > 0 ? i++ : -1);
}
-static int dpdk_recv(pktio_entry_t *pktio_entry ODP_UNUSED,
- odp_packet_t pkt_table[] ODP_UNUSED,
- unsigned num ODP_UNUSED)
+static inline int pkt_to_mbuf(pktio_entry_t *pktio_entry,
+ struct rte_mbuf *mbuf_table[],
+ odp_packet_t pkt_table[], uint16_t num)
{
- return 0;
+ pkt_dpdk_t *pkt_dpdk = &pktio_entry->s.pkt_dpdk;
+ int i;
+ char *data;
+ uint16_t pkt_len;
+
+ for (i = 0; i < num; i++) {
+ mbuf_table[i] = rte_pktmbuf_alloc(pkt_dpdk->pkt_pool);
+ if (mbuf_table[i] == NULL) {
+ ODP_ERR("Failed to alloc mbuf\n");
+ return -1;
+ }
+
+ rte_pktmbuf_reset(mbuf_table[i]);
+ pkt_len = odp_packet_len(pkt_table[i]);
+
+ data = rte_pktmbuf_append(mbuf_table[i], pkt_len);
+
+ if (data != NULL)
+ odp_packet_copydata_out(pkt_table[i], 0, pkt_len, data);
+ }
+ return i;
}
-static int dpdk_send_queue(pktio_entry_t *pktio_entry ODP_UNUSED,
- int index ODP_UNUSED,
- odp_packet_t pkt_table[] ODP_UNUSED,
- int num ODP_UNUSED)
+static int dpdk_recv_queue(pktio_entry_t *pktio_entry,
+ int index,
+ odp_packet_t pkt_table[],
+ int num)
{
- return 0;
+ uint16_t nb_rx;
+
+ struct rte_mbuf *rx_mbufs[num];
+
+ nb_rx = rte_eth_rx_burst(pktio_entry->s.pkt_dpdk.port_id, index,
+ rx_mbufs, num);
+
+ if (nb_rx > 0)
+ nb_rx = mbuf_to_pkt(pktio_entry, pkt_table, rx_mbufs, nb_rx);
+
+ return nb_rx;
}
-static int dpdk_send(pktio_entry_t *pktio_entry ODP_UNUSED,
- odp_packet_t pkt_table[] ODP_UNUSED,
- unsigned num ODP_UNUSED)
+static int dpdk_recv(pktio_entry_t *pktio_entry,
+ odp_packet_t pkt_table[],
+ unsigned num)
{
- return 0;
+ return dpdk_recv_queue(pktio_entry, 0, pkt_table, num);
+}
+
+static int dpdk_send_queue(pktio_entry_t *pktio_entry,
+ int index,
+ odp_packet_t pkt_table[],
+ int num)
+{
+ struct rte_mbuf *tx_mbufs[num];
+ pkt_dpdk_t *pkt_dpdk = &pktio_entry->s.pkt_dpdk;
+ int tx_pkts;
+ int i;
+ int mbufs;
+
+ mbufs = pkt_to_mbuf(pktio_entry, tx_mbufs, pkt_table, num);
+
+ tx_pkts = rte_eth_tx_burst(pkt_dpdk->port_id, index,
+ tx_mbufs, mbufs);
+
+ if (odp_unlikely(tx_pkts < num)) {
+ for (i = tx_pkts; i < mbufs; i++)
+ rte_pktmbuf_free(tx_mbufs[i]);
+ }
+
+ odp_packet_free_multi(pkt_table, tx_pkts);
+
+ if (odp_unlikely(tx_pkts == 0 && __odp_errno != 0))
+ return -1;
+
+ return tx_pkts;
+}
+
+static int dpdk_send(pktio_entry_t *pktio_entry,
+ odp_packet_t pkt_table[],
+ unsigned num)
+{
+ return dpdk_send_queue(pktio_entry, 0, pkt_table, num);
+}
+
+static int dpdk_mac_addr_get(pktio_entry_t *pktio_entry, void *mac_addr)
+{
+ rte_eth_macaddr_get(pktio_entry->s.pkt_dpdk.port_id,
+ (struct ether_addr *)mac_addr);
+ return ETH_ALEN;
}
const pktio_if_ops_t dpdk_pktio_ops = {
@@ -84,7 +570,7 @@ const pktio_if_ops_t dpdk_pktio_ops = {
.mtu_get = NULL,
.promisc_mode_set = NULL,
.promisc_mode_get = NULL,
- .mac_get = NULL,
+ .mac_get = dpdk_mac_addr_get,
.capability = NULL,
.input_queues_config = NULL,
.output_queues_config = NULL,
_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp