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

Reply via email to