diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 1198e5bd02..59f8b96194 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -358,9 +358,6 @@ int stop_L1(module_id_t gnb_id) if (RC.nb_nr_L1_inst > 0) stop_gNB(RC.nb_nr_L1_inst); - if (RC.nb_RU > 0) - stop_RU(RC.nb_RU); - /* stop trx devices, multiple carrier currently not supported by RU */ if (ru->rfdevice.trx_get_stats_func) { ru->rfdevice.trx_get_stats_func(&ru->rfdevice); @@ -378,6 +375,9 @@ int stop_L1(module_id_t gnb_id) LOG_I(GNB_APP, "turned off RU ifdevice\n"); } + if (RC.nb_RU > 0) + stop_RU(RC.nb_RU); + /* release memory used by the RU/gNB threads (incomplete), after all * threads have been stopped (they partially use the same memory) */ for (int inst = 0; inst < RC.nb_RU; inst++) { diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index 0604c7f649..886173cb67 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -535,8 +535,12 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) } // sym_ind } // ant_ind } // vv_inf - if ((*frame & 0x7f) == 0 && *slot == 0 && xran_get_common_counters(gxran_handle, &x_counters[0]) == XRAN_STATUS_SUCCESS) { - for (int o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { + for (int o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { +#if defined F_RELEASE + if ((*frame & 0x7f) == 0 && *slot == 0 && xran_get_common_counters(gxran_handle, &x_counters[0]) == XRAN_STATUS_SUCCESS) { +#elif defined K_RELEASE + if ((*frame & 0x7f) == 0 && *slot == 0 && xran_get_common_counters(gxran_handle[o_xu_id], &x_counters[o_xu_id]) == XRAN_STATUS_SUCCESS) { +#endif LOG_I(HW, "[%s%d][rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld][Total Msgs_Rcvd %ld]\n", "o-du ", diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index f2063b3b91..ca7c1527dd 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -592,10 +592,8 @@ static void get_u128_mask(const paramdef_t *pd, uint64_t *u0t63, uint64_t *u64t1 } } -#if defined F_RELEASE char bbdev_dev[32] = ""; char bbdev_vfio_vf_token[64] = ""; -#endif static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, int nump, const int num_rus) { @@ -666,6 +664,10 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in io_cfg->io_sleep = 0; // enable sleep on PMD cores; 0 -> no sleep io_cfg->nEthLinePerPort = *gpd(fhip, nump, ORAN_CONFIG_NETHPERPORT)->uptr; // 1, 2, 3 total number of links per O-RU (Fronthaul Ethernet link) io_cfg->nEthLineSpeed = *gpd(fhip, nump, ORAN_CONFIG_NETHSPEED)->uptr; // 10G,25G,40G,100G speed of Physical connection on O-RU +#if defined K_RELEASE + io_cfg->num_mbuf_alloc = NUM_MBUFS; // number of mbuf allocated by DPDK (optimal is n = (2^q - 1)) + io_cfg->num_mbuf_vf_alloc = NUM_MBUFS_VF; // number of mbuf allocated by DPDK (optimal is n = (2^q - 1)) +#endif io_cfg->one_vf_cu_plane = (io_cfg->num_vfs == num_rus); // C-plane and U-plane use one VF /* eCPRI One-Way Delay Measurements common settings for O-DU and O-RU; @@ -696,6 +698,48 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in return true; } +#if defined K_RELEASE +static bool set_fh_bbdev_params(struct xran_fh_init *fh_init) +{ + struct xran_io_cfg *io_cfg = &fh_init->io_cfg; + io_cfg->bbdev_dev[0] = NULL; // BBDev dev name; max devices = 1 + fh_init->dpdkVfioVfToken = NULL; // BBDev dev token; max devices = 1 + char *shlibversion = NULL; // version of the LDPC coding library + paramdef_t LoaderParams_shlibversion[] = {{"shlibversion", NULL, 0, .strptr = &shlibversion, .defstrval = NULL, TYPE_STRING, 0, NULL}}; + config_get(config_get_if(), LoaderParams_shlibversion, sizeofArray(LoaderParams_shlibversion), "loader.ldpc"); + if (shlibversion != NULL && strncmp(shlibversion, "_aal", 4) == 0) { + uint32_t is_t2 = 0; // If not 0 then include the BBDEV device in the EAL init for FHI + char *dpdk_dev = NULL; // PCI address of the card + char *vfio_vf_token = NULL; // vfio token for the bbdev card + paramdef_t LoaderParams[] = { + {"is_t2", NULL, 0, .uptr = &is_t2, .defuintval = 0, TYPE_UINT, 0, NULL}, + {"dpdk_dev", NULL, 0, .strptr = &dpdk_dev, .defstrval = NULL, TYPE_STRING, 0, NULL}, + {"vfio_vf_token", NULL, 0, .strptr = &vfio_vf_token, .defstrval = NULL, TYPE_STRING, 0, NULL} + }; + config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), "nrLDPC_coding_aal"); + + if (!is_t2) { + AssertFatal(dpdk_dev!=NULL, "nrLDPC_coding_aal.dpdk_dev was not provided"); + snprintf(&bbdev_dev[0], sizeof(bbdev_dev), "%s", dpdk_dev); + io_cfg->bbdev_dev[0] = &bbdev_dev[0]; // BBDev dev name; max devices = 1 + if(vfio_vf_token != NULL) { + snprintf(&bbdev_vfio_vf_token[0], sizeof(bbdev_vfio_vf_token), "%s", vfio_vf_token); + fh_init->dpdkVfioVfToken = &bbdev_vfio_vf_token[0]; // BBDev dev token; max devices = 1 + } else { + fh_init->dpdkVfioVfToken = NULL; // BBDev dev token; max devices = 1 + } + io_cfg->bbdev_mode = XRAN_BBDEV_MODE_HW_ON; // DPDK for BBDev + } else { + io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev + } + } else { + io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev + } + + return true; +} +#endif + #ifdef OAI_MPLANE static bool set_fh_eaxcid_conf_mplane(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat, const ru_session_list_t *ru_session_list) { @@ -820,6 +864,8 @@ static bool set_fh_init(void *mplane_api, struct xran_fh_init *fh_init, enum xra if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus)) return false; #if defined K_RELEASE + if (!set_fh_bbdev_params(fh_init)) + return false; for (int32_t o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { if (!set_fh_eaxcid_conf_mplane(&fh_init->eAxCId_conf[o_xu_id], xran_cat, ru_session_list)) return false; @@ -853,6 +899,8 @@ static bool set_fh_init(void *mplane_api, struct xran_fh_init *fh_init, enum xra if (!set_fh_io_cfg(&fh_init->io_cfg, fhip, nump, num_rus)) return false; #if defined K_RELEASE + if (!set_fh_bbdev_params(fh_init)) + return false; for (int32_t o_xu_id = 0; o_xu_id < fh_init->xran_ports; o_xu_id++) { if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf[o_xu_id], xran_cat)) return false; @@ -1112,6 +1160,19 @@ static bool set_fh_per_mu_cfg(void *mplane_api, int ru_idx, int num_rus, const o return true; } +xran_active_numerologies_per_tti activeMUs; + +static bool set_activeMUs(xran_active_numerologies_per_tti *p_activeMUs, uint8_t mu) +{ + for (int i = 0; i < XRAN_N_FE_BUF_LEN; i++) { + for (int j = 0; j < XRAN_MAX_NUM_MU; j++) { + p_activeMUs->numerology[i][j] = j == mu; + } + } + return true; +} +#endif + static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_category xran_cat, const openair0_config_t *oai0, struct xran_fh_config *fh_config) { AssertFatal(num_rus == 1 || num_rus == 2, "only support 1 or 2 RUs as of now\n"); @@ -1159,7 +1220,11 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->sector_id = 0; // Band sector ID for FH; not used in xran fh_config->nCC = 1; // number of Component carriers supported on FH; M-plane info fh_config->neAxc = RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH) +#if defined K_RELEASE + fh_config->neAxcUl = oai0->rx_num_channels / num_rus; // number of eAxc supported on one CC for UL direction = PUSCH +#elif defined F_RELEASE fh_config->neAxcUl = 0; // number of eAxc supported on one CC for UL direction = PUSCH; used only if XRAN_CATEGORY_B +#endif fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B #if defined F_RELEASE fh_config->nDLFftSize = oai0->split7.fftSize; // DL FFT size; not used in xran @@ -1217,6 +1282,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->GPS_Beta = 0; // beta value as defined in section 9.7.2 of ORAN spec. range -32767 ~ +32767; offset_sec = pConf->GPS_Beta / 100 #if defined K_RELEASE fh_config->numMUs = 1; + fh_config->mu_number[0] = mu_number; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz, 4 -> 240kHz */ fh_config->nNumerology[0] = mu_number; /* 0 -> 15kHz, 1 -> 30kHz, 2 -> 60kHz, 3 -> 120kHz, 4 -> 240kHz */ #elif defined F_RELEASE if (!set_fh_prach_config(mplane_api, oai0, fh_config->neAxc, prachp, nprach, &fh_config->prach_conf)) @@ -1261,6 +1327,11 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->dssEnable = 0; // enable DSS (extension-9) fh_config->dssPeriod = 0; // DSS pattern period for LTE/NR // fh_config->technology[XRAN_MAX_DSS_PERIODICITY] // technology array represents slot is LTE(0)/NR(1); used only if DSS enabled +#if defined K_RELEASE + if (!set_activeMUs(&activeMUs, oai0->nr_scs_for_raster)) + return false; + fh_config->activeMUs = &activeMUs; +#endif return true; } diff --git a/radio/fhi_72/oran-init.c b/radio/fhi_72/oran-init.c index b575309635..315347e7d1 100644 --- a/radio/fhi_72/oran-init.c +++ b/radio/fhi_72/oran-init.c @@ -27,7 +27,11 @@ // structure holding allocated memory for ports (multiple DUs) and sectors // (multiple CCs) static oran_port_instance_t gPortInst[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; +#if defined F_RELEASE void *gxran_handle; +#elif defined K_RELEASE +void *gxran_handle[XRAN_PORTS_NUM]; +#endif static struct xran_fh_init g_fh_init = {0}; static struct xran_fh_config g_fh_config[XRAN_PORTS_NUM] = {0}; @@ -383,21 +387,44 @@ static void oran_allocate_buffers(void *handle, #endif } -int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_config *xran_fh_config) +void *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_config *xran_fh_config) { int32_t xret = 0; +#if defined K_RELEASE + xran_mem_mgr_leak_detector_init(); +#endif + print_fh_init(xran_fh_init); +#if defined F_RELEASE xret = xran_init(0, NULL, xran_fh_init, NULL, &gxran_handle); +#elif defined K_RELEASE + xret = xran_init(0, NULL, xran_fh_init, NULL, gxran_handle); +#endif if (xret != XRAN_STATUS_SUCCESS) { printf("xran_init failed %d\n", xret); exit(-1); } +#if defined K_RELEASE + for (int32_t o_xu_id = 0; o_xu_id < xran_fh_init->xran_ports; o_xu_id++) { + if (gxran_handle[o_xu_id] == NULL) { + printf("xran_init for RU%d failed\n", o_xu_id); + exit(-1); + } else { + printf("RU%d handle = %p\n", o_xu_id, gxran_handle[o_xu_id]); + } + } +#endif + /** process all the O-RU|O-DU for use case */ for (int32_t o_xu_id = 0; o_xu_id < xran_fh_init->xran_ports; o_xu_id++) { print_fh_config(&xran_fh_config[o_xu_id]); +#if defined F_RELEASE xret = xran_open(gxran_handle, &xran_fh_config[o_xu_id]); +#elif defined K_RELEASE + xret = xran_open(gxran_handle[o_xu_id], &xran_fh_config[o_xu_id]); +#endif if (xret != XRAN_STATUS_SUCCESS) { printf("xran_open failed %d\n", xret); exit(-1); @@ -409,14 +436,15 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi struct xran_cb_tag tag = {.cellId = sector, .oXuId = o_xu_id}; pi->prach_tag = tag; pi->pusch_tag = tag; - oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]); #if defined K_RELEASE - if ((xret = xran_timingsource_reg_tticb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) { + oran_allocate_buffers(gxran_handle[0], o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]); + if ((xret = xran_timingsource_reg_tticb(NULL, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) { printf("xran_timingsource_reg_tticb failed %d\n", xret); exit(-1); } #elif defined F_RELEASE + oran_allocate_buffers(gxran_handle, o_xu_id, 1, pi, xran_fh_init->mtu, &xran_fh_config[o_xu_id]); if ((xret = xran_reg_physide_cb(gxran_handle, oai_physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI)) != XRAN_STATUS_SUCCESS) { printf("xran_reg_physide_cb failed %d\n", xret); exit(-1); @@ -445,7 +473,7 @@ int *oai_oran_initialize(struct xran_fh_init *xran_fh_init, struct xran_fh_confi memcpy(&g_fh_init, xran_fh_init, sizeof(*xran_fh_init)); memcpy(&g_fh_config, xran_fh_config, sizeof(*xran_fh_config) * xran_fh_init->xran_ports); - return (void *)gxran_handle; + return gxran_handle; } oran_buf_list_t *get_xran_buffers(uint32_t port_id) diff --git a/radio/fhi_72/oran-init.h b/radio/fhi_72/oran-init.h index ed1076d483..135e2cf307 100644 --- a/radio/fhi_72/oran-init.h +++ b/radio/fhi_72/oran-init.h @@ -41,9 +41,13 @@ typedef struct oran_port_instance_t { } oran_port_instance_t; extern struct xran_fh_config gxran_fh_config[XRAN_PORTS_NUM]; +#if defined F_RELEASE extern void *gxran_handle; +#elif defined K_RELEASE +extern void *gxran_handle[XRAN_PORTS_NUM]; +#endif -int *oai_oran_initialize(struct xran_fh_init *fh_init, struct xran_fh_config *fh_config); +void *oai_oran_initialize(struct xran_fh_init *fh_init, struct xran_fh_config *fh_config); oran_buf_list_t *get_xran_buffers(uint32_t port_id); struct xran_fh_init *get_xran_fh_init(void); diff --git a/radio/fhi_72/oran.h b/radio/fhi_72/oran.h index 08d7574f49..d322f35f1e 100644 --- a/radio/fhi_72/oran.h +++ b/radio/fhi_72/oran.h @@ -13,11 +13,4 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot); int transport_init(openair0_device_t *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params); -typedef struct { - eth_state_t e; - shared_buffers buffers; - rru_config_msg_type_t last_msg; - int capabilities_sent; - void *oran_priv; -} oran_eth_state_t; #endif /* _ORAN_H_ */ diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 3a670f5f7f..fd6ba98232 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -34,6 +34,8 @@ typedef struct { int capabilities_sent; void *oran_priv; void *mplane_priv; + uint32_t nCC; + uint32_t num_ports; } oran_eth_state_t; notifiedFIFO_t oran_sync_fifo; @@ -45,12 +47,53 @@ int trx_oran_start(openair0_device_t *device) oran_eth_state_t *s = device->priv; // Start ORAN +#if defined K_RELEASE + if (xran_timingsource_start() != 0) { + printf("%s:%d:%s: Start timing source failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } else { + printf("Start timing source. Done\n"); + } + + if (xran_start_worker_threads() != 0) { + printf("%s:%d:%s: Start worker thread failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } else { + printf("Start worker thread. Done\n"); + } + + xran_mem_mgr_leak_detector_display(0); +#endif + +#if defined F_RELEASE if (xran_start(s->oran_priv) != 0) { printf("%s:%d:%s: Start ORAN failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__); exit(1); - } else { - printf("Start ORAN. Done\n"); } +#elif defined K_RELEASE + for (int32_t port_id = 0; port_id < s->num_ports; port_id++) { + if (xran_start(((void **)s->oran_priv)[port_id]) != 0) { + printf("%s:%d:%s: Start ORAN port ID %d failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__, port_id); + exit(1); + } + } +#endif + + printf("Start ORAN. Done\n"); + +#if defined K_RELEASE + for (int32_t cc_id = 0; cc_id < s->nCC; cc_id++) { + for (int32_t port_id = 0; port_id < s->num_ports; port_id++) { + if (xran_activate_cc(port_id, cc_id) != 0) { + printf("%s:%d:%s: Activate CC failed ... Exit\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } else { + printf("Activate CC. Done\n"); + } + } + } +#endif + return 0; } @@ -58,14 +101,39 @@ void trx_oran_end(openair0_device_t *device) { printf("ORAN: %s\n", __FUNCTION__); oran_eth_state_t *s = device->priv; +#if defined K_RELEASE + xran_shutdown(s->oran_priv); +#endif xran_close(s->oran_priv); +#if defined K_RELEASE + xran_cleanup(); + xran_mem_mgr_leak_detector_destroy(); +#endif } int trx_oran_stop(openair0_device_t *device) { printf("ORAN: %s\n", __FUNCTION__); oran_eth_state_t *s = device->priv; + +#if defined K_RELEASE + for (int32_t cc_id = 0; cc_id < s->nCC; cc_id++) { + for (int32_t port_id = 0; port_id < s->num_ports; port_id++) { + xran_deactivate_cc(port_id, cc_id); + } + } + + xran_timingsource_stop(); +#endif + +#if defined F_RELEASE xran_stop(s->oran_priv); +#elif defined K_RELEASE + for (int32_t port_id = 0; port_id < s->num_ports; port_id++) { + xran_stop(((void **)s->oran_priv)[port_id]); + } +#endif + #ifdef OAI_MPLANE printf("[MPLANE] Stopping M-plane.\n"); disconnect_mplane(s->mplane_priv); @@ -395,6 +463,8 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device_t eth->e.compression = NO_COMPRESS; eth->e.if_name = eth_params->local_if_name; eth->last_msg = (rru_config_msg_type_t)-1; + eth->nCC = fh_config->nCC; + eth->num_ports = fh_init.xran_ports; device->transp_type = ETHERNET_TP; device->trx_start_func = trx_oran_start;