X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=fhi_lib%2Flib%2Fethernet%2Fethdi.c;h=873db7b8961c666d3ebc3fd68262c2523487b8ee;hb=70d9d920dd4e575f085f1f1a9050fefd1c10e127;hp=3664ecc48ea4a5f9a9adc2d8ccc9565ca692a31b;hpb=4745e5c88ba931c6d71cb6d8c681f76cf364eac5;p=o-du%2Fphy.git diff --git a/fhi_lib/lib/ethernet/ethdi.c b/fhi_lib/lib/ethernet/ethdi.c index 3664ecc..873db7b 100644 --- a/fhi_lib/lib/ethernet/ethdi.c +++ b/fhi_lib/lib/ethernet/ethdi.c @@ -16,7 +16,6 @@ * *******************************************************************************/ - /** * @brief This file has all definitions for the Ethernet Data Interface Layer * @file ethdi.c @@ -24,6 +23,7 @@ * @author Intel Corporation **/ +#define _GNU_SOURCE #include #include #include @@ -63,14 +63,14 @@ #include "ethernet.h" #include "ethdi.h" -#ifndef MLOG_ENABLED -#include "../src/mlog_lnx_xRAN.h" -#else -#include "mlog_lnx.h" -#endif +#include "xran_fh_o_du.h" +#include "xran_mlog_lnx.h" +#include "xran_printf.h" #include "../src/xran_lib_mlog_tasks_id.h" +#define BURST_RX_IO_SIZE 48 + struct xran_ethdi_ctx g_ethdi_ctx = { 0 }; enum xran_if_state xran_if_current_state = XRAN_STOPPED; @@ -79,37 +79,30 @@ struct rte_mbuf *xran_ethdi_mbuf_alloc(void) return rte_pktmbuf_alloc(_eth_mbuf_pool); } -int xran_ethdi_mbuf_send(struct rte_mbuf *mb, uint16_t ethertype) +int32_t xran_ethdi_mbuf_send(struct rte_mbuf *mb, uint16_t ethertype, uint16_t vf_id) { struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx(); int res = 0; - mb->port = ctx->io_cfg.port[ETHDI_UP_VF]; - xran_add_eth_hdr_vlan(&ctx->entities[ID_RU], ethertype, mb, ctx->up_vtag); + mb->port = ctx->io_cfg.port[vf_id]; + xran_add_eth_hdr_vlan(&ctx->entities[vf_id][ID_O_RU], ethertype, mb); - res = xran_enqueue_mbuf(mb, ctx->tx_ring[ETHDI_UP_VF]); + res = xran_enqueue_mbuf(mb, ctx->tx_ring[vf_id]); return res; } -int xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype) +int32_t xran_ethdi_mbuf_send_cp(struct rte_mbuf *mb, uint16_t ethertype, uint16_t vf_id) { struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx(); int res = 0; - mb->port = ctx->io_cfg.port[ETHDI_CP_VF]; - xran_add_eth_hdr_vlan(&ctx->entities[ID_RU], ethertype, mb, ctx->cp_vtag); + mb->port = ctx->io_cfg.port[vf_id]; + xran_add_eth_hdr_vlan(&ctx->entities[vf_id][ID_O_RU], ethertype, mb); - res = xran_enqueue_mbuf(mb, ctx->tx_ring[ETHDI_CP_VF]); + res = xran_enqueue_mbuf(mb, ctx->tx_ring[vf_id]); return res; } -void xran_ethdi_stop_tx() -{ - struct xran_ethdi_ctx *const ctx = xran_ethdi_get_ctx(); - rte_timer_stop_sync(&ctx->timer_tx); -} - - struct { uint16_t ethertype; ethertype_handler fn; @@ -121,7 +114,7 @@ struct { -int xran_register_ethertype_handler(uint16_t ethertype, ethertype_handler callback) +int32_t xran_register_ethertype_handler(uint16_t ethertype, ethertype_handler callback) { int i; @@ -157,20 +150,7 @@ int xran_ethdi_filter_packet(struct rte_mbuf *pkt, uint64_t rx_time) { struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx(); -#ifdef VLAN_SUPPORT - if (rte_vlan_strip(pkt) == 0) { - if (pkt->vlan_tci == ctx->cp_vtag) { - dlog("VLAN tci matches %d", pkt->vlan_tci); - } else { - wlog("packet with wrong VLAN tag %d, dropping", - pkt->vlan_tci); - return 0; - } - } else - dlog("Packet not vlan tagged"); -#endif - - const struct ether_hdr *eth_hdr = rte_pktmbuf_mtod(pkt, void *); + const struct rte_ether_hdr *eth_hdr = rte_pktmbuf_mtod(pkt, void *); #if defined(DPDKIO_DEBUG) && DPDKIO_DEBUG > 1 nlog("*** processing RX'ed packet of size %d ***", @@ -200,39 +180,139 @@ int xran_ethdi_filter_packet(struct rte_mbuf *pkt, uint64_t rx_time) return xran_handle_ether(rte_be_to_cpu_16(eth_hdr->ether_type), pkt, rx_time); } +/* Check the link status of all ports in up to 9s, and print them finally */ +static void check_port_link_status(uint8_t portid) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ + uint8_t count, all_ports_up, print_flag = 0; + struct rte_eth_link link; + printf("\nChecking link status portid [%d] ", portid); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + all_ports_up = 1; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + + /* print link status if flag set */ + if (print_flag == 1) { + if (link.link_status) + printf("Port %d Link Up - speed %u " + "Mbps - %s\n", (uint8_t)portid, + (unsigned)link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + else + printf("Port %d Link Down\n", + (uint8_t)portid); + } + /* clear all_ports_up flag if any link down */ + if (link.link_status == ETH_LINK_DOWN) { + all_ports_up = 0; + break; + } + /* after finally printing all link status, get out */ + if (print_flag == 1) + break; + + if (all_ports_up == 0) { + printf("."); + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + + /* set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { + print_flag = 1; + printf(" ... done\n"); + } + } +} -int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg, - int *lcore_id, struct ether_addr *p_lls_cu_addr, struct ether_addr *p_ru_addr, - uint16_t cp_vlan, uint16_t up_vlan) +int32_t +xran_ethdi_init_dpdk_io(char *name, const struct xran_io_cfg *io_cfg, + int *lcore_id, struct rte_ether_addr *p_o_du_addr, + struct rte_ether_addr *p_ru_addr) { - uint16_t port[2] = {0, 0}; + uint16_t port[XRAN_VF_MAX]; struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx(); - int i; - char core_mask[20]; - char *argv[] = { name, core_mask, "-m3072", "--proc-type=auto", - "--file-prefix", name, "-w", "0000:00:00.0" }; + int i,ivf; + char core_mask[64]; + uint64_t c_mask = 0; + uint64_t nWorkerCore = 1; + uint32_t coreNum = sysconf(_SC_NPROCESSORS_CONF); + char bbdev_wdev[32] = ""; + char bbdev_vdev[32] = ""; + char iova_mode[32] = "--iova-mode=pa"; + char socket_mem[32] = "--socket-mem=8192"; + char socket_limit[32] = "--socket-limit=8192"; + char ring_name[32] = ""; + + char *argv[] = { name, core_mask, "-n2", iova_mode, socket_mem, socket_limit, "--proc-type=auto", + "--file-prefix", name, "-w", "0000:00:00.0", bbdev_wdev, bbdev_vdev}; if (io_cfg == NULL) return 0; + if(io_cfg->bbdev_mode != XRAN_BBDEV_NOT_USED){ + printf("BBDEV_FEC_ACCL_NR5G\n"); + if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_ON){ + // hw-accelerated bbdev + printf("hw-accelerated bbdev %s\n", io_cfg->bbdev_dev[0]); + snprintf(bbdev_wdev, RTE_DIM(bbdev_wdev), "-w %s", io_cfg->bbdev_dev[0]); + } else if (io_cfg->bbdev_mode == XRAN_BBDEV_MODE_HW_OFF){ + // hw-accelerated bbdev disable + if(io_cfg->bbdev_dev[0]){ + printf("hw-accelerated bbdev disable %s\n", io_cfg->bbdev_dev[0]); + snprintf(bbdev_wdev, RTE_DIM(bbdev_wdev), "-b %s", io_cfg->bbdev_dev[0]); + } + snprintf(bbdev_wdev, RTE_DIM(bbdev_wdev), "%s", "--vdev=baseband_turbo_sw"); + } else { + rte_panic("Cannot init DPDK incorrect [bbdev_mode %d]\n", io_cfg->bbdev_mode); + } + } + + if (io_cfg->dpdkIoVaMode == 1){ + snprintf(iova_mode, RTE_DIM(iova_mode), "%s", "--iova-mode=va"); + } + + if (io_cfg->dpdkMemorySize){ + snprintf(socket_mem, RTE_DIM(socket_mem), "--socket-mem=%d", io_cfg->dpdkMemorySize); + snprintf(socket_limit, RTE_DIM(socket_limit), "--socket-limit=%d", io_cfg->dpdkMemorySize); + } + + c_mask = (long)(1L << io_cfg->core) | + (long)(1L << io_cfg->system_core) | + (long)(1L << io_cfg->timing_core); + + nWorkerCore = 1L; + for (i = 0; i < coreNum; i++) { + if (nWorkerCore & (uint64_t)io_cfg->pkt_proc_core) { + c_mask |= nWorkerCore; + } + nWorkerCore = nWorkerCore << 1; + } + + printf("total cores %d c_mask 0x%lx core %d [id] system_core %d [id] pkt_proc_core 0x%lx [mask] pkt_aux_core %d [id] timing_core %d [id]\n", + coreNum, c_mask, io_cfg->core, io_cfg->system_core, io_cfg->pkt_proc_core, io_cfg->pkt_aux_core, io_cfg->timing_core); - snprintf(core_mask, sizeof(core_mask), "-c%x", - (1 << io_cfg->core) | - (1 << io_cfg->system_core) | - (1 << io_cfg->pkt_proc_core) | - (1 << io_cfg->pkt_aux_core) | - (1 << io_cfg->timing_core)); + snprintf(core_mask, sizeof(core_mask), "-c 0x%lx", c_mask); ctx->io_cfg = *io_cfg; - ctx->ping_state = PING_IDLE; - ctx->known_peers = 1; - ctx->busy_poll_till = rte_rdtsc(); - ctx->cp_vtag = cp_vlan; - ctx->up_vtag = up_vlan; - for (i = 0; i <= ID_BROADCAST; i++) /* Initialize all as broadcast */ - memset(&ctx->entities[i], 0xFF, sizeof(ctx->entities[0])); + for (ivf = 0; ivf < XRAN_VF_MAX; ivf++){ + for (i = 0; i <= ID_BROADCAST; i++) /* Initialize all as broadcast */ + memset(&ctx->entities[ivf][i], 0xFF, sizeof(ctx->entities[0][0])); + } + + printf("%s: Calling rte_eal_init:", __FUNCTION__); + for (i = 0; i < RTE_DIM(argv); i++) + { + printf("%s ", argv[i]); + } + printf("\n"); + /* This will return on system_core, which is not necessarily the * one we're on right now. */ @@ -241,6 +321,11 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg, xran_init_mbuf_pool(); +#ifdef RTE_LIBRTE_PDUMP + /* initialize packet capture framework */ + rte_pdump_init(); +#endif + /* Timers. */ rte_timer_subsystem_init(); rte_timer_init(&ctx->timer_ping); @@ -251,27 +336,46 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg, PANIC_ON(*lcore_id == RTE_MAX_LCORE, "out of lcores for io_loop()"); + for (i = 0; i < XRAN_VF_MAX; i++) + port[i] = 0xffff; + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { - for (i = 0; i < ETHDI_VF_MAX; i ++){ - if (rte_eth_dev_attach(io_cfg->dpdk_dev[i], &port[i]) != 0 || - rte_eth_dev_count_avail() == 0) - errx(1, "Network port doesn't exist."); - xran_init_port(port[i], p_lls_cu_addr); /* we only have 1 port at this stage */ - if(i==0){ - ctx->tx_ring[i] = rte_ring_create("tx_ring_up", NUM_MBUFS, - rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); - ctx->rx_ring[i] = rte_ring_create("rx_ring_up", NUM_MBUFS, + for (i = 0; i < XRAN_VF_MAX && i < io_cfg->num_vfs; i++){ + if(io_cfg->dpdk_dev[i]){ + struct rte_dev_iterator iterator; + uint16_t port_id; + + if (rte_dev_probe(io_cfg->dpdk_dev[i]) != 0 || + rte_eth_dev_count_avail() == 0) { + errx(1, "Network port doesn't exist\n"); + } + + RTE_ETH_FOREACH_MATCHING_DEV(port_id, io_cfg->dpdk_dev[i], &iterator){ + port[i] = port_id; + xran_init_port(port[i]); + } + } else { + printf("no DPDK port provided\n"); + } + + if(!(i & 1) ){ + snprintf(ring_name, RTE_DIM(ring_name), "%s_%d", "tx_ring_up", i); + ctx->tx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); - ctx->pkt_dump_ring[i] = rte_ring_create("pkt_dump_ring_up", NUM_MBUFS, + snprintf(ring_name, RTE_DIM(ring_name), "%s_%d", "rx_ring_up", i); + ctx->rx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); }else { - ctx->tx_ring[i] = rte_ring_create("tx_ring_cp", NUM_MBUFS, + snprintf(ring_name, RTE_DIM(ring_name), "%s_%d", "tx_ring_cp", i); + ctx->tx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); - ctx->rx_ring[i] = rte_ring_create("rx_ring_cp", NUM_MBUFS, - rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); - ctx->pkt_dump_ring[i] = rte_ring_create("pkt_dump_ring_cp", NUM_MBUFS, + snprintf(ring_name, RTE_DIM(ring_name), "%s_%d", "rx_ring_cp", i); + ctx->rx_ring[i] = rte_ring_create(ring_name, NUM_MBUFS_RING, rte_lcore_to_socket_id(*lcore_id), RING_F_SC_DEQ); } + if(io_cfg->dpdk_dev[i]){ + check_port_link_status(port[i]); + } } } else { rte_panic("ethdi_dpdk_io_loop() failed to start with RTE_PROC_SECONDARY\n"); @@ -279,15 +383,33 @@ int xran_ethdi_init_dpdk_io(char *name, const struct xran_io_loop_cfg *io_cfg, PANIC_ON(ctx->tx_ring == NULL, "failed to allocate tx ring"); PANIC_ON(ctx->rx_ring == NULL, "failed to allocate rx ring"); PANIC_ON(ctx->pkt_dump_ring == NULL, "failed to allocate pkt dumping ring"); - for (i = 0; i < ETHDI_VF_MAX; i++) + for (i = 0; i < XRAN_VF_MAX && i < io_cfg->num_vfs; i++){ ctx->io_cfg.port[i] = port[i]; + print_dbg("port_id 0x%04x\n", ctx->io_cfg.port[i]); + } - rte_eth_macaddr_get(port[ETHDI_UP_VF], &ctx->entities[io_cfg->id]); - ether_addr_copy(p_ru_addr, &ctx->entities[ID_RU]); - - /* Start the actual IO thread */ - if (rte_eal_remote_launch(xran_ethdi_dpdk_io_loop, &ctx->io_cfg, *lcore_id)) - rte_panic("ethdi_dpdk_io_loop() failed to start\n"); + for (i = 0; i < XRAN_VF_MAX && i < io_cfg->num_vfs; i++){ + if(io_cfg->dpdk_dev[i]){ + struct rte_ether_addr *p_addr; + rte_eth_macaddr_get(port[i], &ctx->entities[i][io_cfg->id]); + + p_addr = &ctx->entities[i][io_cfg->id]; + printf("vf %u local SRC MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 + " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", + (unsigned)i, + p_addr->addr_bytes[0], p_addr->addr_bytes[1], p_addr->addr_bytes[2], + p_addr->addr_bytes[3], p_addr->addr_bytes[4], p_addr->addr_bytes[5]); + + p_addr = &p_ru_addr[i]; + printf("vf %u remote DST MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 + " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", + (unsigned)i, + p_addr->addr_bytes[0], p_addr->addr_bytes[1], p_addr->addr_bytes[2], + p_addr->addr_bytes[3], p_addr->addr_bytes[4], p_addr->addr_bytes[5]); + + rte_ether_addr_copy(&p_ru_addr[i], &ctx->entities[i][ID_O_RU]); + } + } return 1; } @@ -308,6 +430,7 @@ static inline uint16_t xran_tx_from_ring(int port, struct rte_ring *r) while (1) { /* When tx queue is full it is trying again till succeed */ t1 = MLogTick(); sent += rte_eth_tx_burst(port, 0, &mbufs[sent], dequeued - sent); + MLogTask(PID_RADIO_ETH_TX_BURST, t1, MLogTick()); if (sent == dequeued) @@ -315,62 +438,41 @@ static inline uint16_t xran_tx_from_ring(int port, struct rte_ring *r) } } - - -/* - * This is the main DPDK-IO loop. - * This will sleep if there's no packets incoming and there's - * no work enqueued, sleep lenth is defined in IDLE_SLEEP_MICROSECS - */ -int xran_ethdi_dpdk_io_loop(void *io_loop_cfg) +int32_t process_dpdk_io(void) { struct xran_ethdi_ctx *ctx = xran_ethdi_get_ctx(); - const struct xran_io_loop_cfg *const cfg = io_loop_cfg; - const int port[ETHDI_VF_MAX] = {cfg->port[ETHDI_UP_VF], cfg->port[ETHDI_CP_VF]}; + struct xran_io_cfg * cfg = &(xran_ethdi_get_ctx()->io_cfg); + int32_t* port = &cfg->port[0]; int port_id = 0; - struct sched_param sched_param; - int res = 0; - - printf("%s [PORT: %d %d] [CPU %2d] [PID: %6d]\n", __FUNCTION__, port[ETHDI_UP_VF], port[ETHDI_CP_VF] , rte_lcore_id(), getpid()); - - printf("%s [CPU %2d] [PID: %6d]\n", __FUNCTION__, rte_lcore_id(), getpid()); - sched_param.sched_priority = XRAN_THREAD_DEFAULT_PRIO; - if ((res = pthread_setschedparam(pthread_self(), SCHED_FIFO, &sched_param))) - { - printf("priority is not changed: coreId = %d, result1 = %d\n",rte_lcore_id(), res); - } - for (;;) { - for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++){ - struct rte_mbuf *mbufs[BURST_SIZE]; - /* RX */ - const uint16_t rxed = rte_eth_rx_burst(port[port_id], 0, mbufs, BURST_SIZE); - if (rxed != 0){ - long t1 = MLogTick(); - rte_ring_enqueue_burst(ctx->rx_ring[port_id], (void*)mbufs, rxed, NULL); - MLogTask(PID_RADIO_RX_VALIDATE, t1, MLogTick()); - } + rte_timer_manage(); - /* TX */ - const uint16_t sent = xran_tx_from_ring(port[port_id], ctx->tx_ring[port_id]); - if (rxed | sent) - continue; /* more packets might be waiting in queues */ + for (port_id = 0; port_id < XRAN_VF_MAX && port_id < ctx->io_cfg.num_vfs; port_id++){ + struct rte_mbuf *mbufs[BURST_RX_IO_SIZE]; + if(port[port_id] == 0xFF) + return 0; - rte_pause(); /* short pause, optimize memory access */ - if (XRAN_STOPPED == xran_if_current_state) - break; + /* RX */ + const uint16_t rxed = rte_eth_rx_burst(port[port_id], 0, mbufs, BURST_RX_IO_SIZE); + if (rxed != 0){ + unsigned enq_n = 0; + long t1 = MLogTick(); + enq_n = rte_ring_enqueue_burst(ctx->rx_ring[port_id], (void*)mbufs, rxed, NULL); + if(rxed - enq_n) + rte_panic("error enq\n"); + MLogTask(PID_RADIO_RX_VALIDATE, t1, MLogTick()); } + /* TX */ + const uint16_t sent = xran_tx_from_ring(port[port_id], ctx->tx_ring[port_id]); + if (XRAN_STOPPED == xran_if_current_state) - break; + return -1; } - fflush(stderr); - fflush(stdout); - puts("IO loop finished"); - - //for (port_id = 0; port_id < ETHDI_VF_MAX; port_id++) - // xran_ethdi_port_stats(port[port_id]); + if (XRAN_STOPPED == xran_if_current_state) + return -1; return 0; } +