Commit ab2dd20b authored by Raymond Knopp's avatar Raymond Knopp Committed by Robert Schmidt

Replace app_io_xran_fh_init_init() and app_io_xran_fh_config_init()

Replace app_io_xran_fh_init_init() -> set_fh_init()
Replace app_io_xran_fh_config_init() -> set_fh_config()

The previous app_io_xran_fh_config_init() also initialized the prb_map.
Towards our own setup of buffers, temporarily introduce setup_vrbmap()
to set up the missing prb_map.
parent e8ce3686
......@@ -483,382 +483,6 @@ void app_io_xran_if_stop(void)
}
}
int32_t
app_io_xran_eAxCid_conf_set(struct xran_eaxcid_config *p_eAxC_cfg, RuntimeConfig * p_s_cfg)
{
int32_t shift;
uint16_t mask;
if(p_s_cfg->DU_Port_ID_bitwidth && p_s_cfg->BandSector_ID_bitwidth && p_s_cfg->CC_ID_bitwidth
&& p_s_cfg->RU_Port_ID_bitwidth &&
(p_s_cfg->DU_Port_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth + p_s_cfg->CC_ID_bitwidth
+ p_s_cfg->RU_Port_ID_bitwidth) == 16 /* eAxC ID subfields are 16 bits */
){ /* bit mask provided */
mask = 0;
p_eAxC_cfg->bit_ruPortId = 0;
for (shift = 0; shift < p_s_cfg->RU_Port_ID_bitwidth; shift++){
mask |= 1 << shift;
}
p_eAxC_cfg->mask_ruPortId = mask;
p_eAxC_cfg->bit_ccId = p_s_cfg->RU_Port_ID_bitwidth;
mask = 0;
for (shift = p_s_cfg->RU_Port_ID_bitwidth; shift < p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth; shift++){
mask |= 1 << shift;
}
p_eAxC_cfg->mask_ccId = mask;
p_eAxC_cfg->bit_bandSectorId = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth;
mask = 0;
for (shift = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth; shift < p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth; shift++){
mask |= 1 << shift;
}
p_eAxC_cfg->mask_bandSectorId = mask;
p_eAxC_cfg->bit_cuPortId = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth;
mask = 0;
for (shift = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth;
shift < p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth + p_s_cfg->DU_Port_ID_bitwidth; shift++){
mask |= 1 << shift;
}
p_eAxC_cfg->mask_cuPortId = mask;
} else { /* bit mask config is not provided */
switch (p_s_cfg->xranCat){
case XRAN_CATEGORY_A: {
p_eAxC_cfg->mask_cuPortId = 0xf000;
p_eAxC_cfg->mask_bandSectorId = 0x0f00;
p_eAxC_cfg->mask_ccId = 0x00f0;
p_eAxC_cfg->mask_ruPortId = 0x000f;
p_eAxC_cfg->bit_cuPortId = 12;
p_eAxC_cfg->bit_bandSectorId = 8;
p_eAxC_cfg->bit_ccId = 4;
p_eAxC_cfg->bit_ruPortId = 0;
break;
}
case XRAN_CATEGORY_B: {
p_eAxC_cfg->mask_cuPortId = 0xf000;
p_eAxC_cfg->mask_bandSectorId = 0x0c00;
p_eAxC_cfg->mask_ccId = 0x0300;
p_eAxC_cfg->mask_ruPortId = 0x00ff; /* more than [0-127] eAxC */
p_eAxC_cfg->bit_cuPortId = 12;
p_eAxC_cfg->bit_bandSectorId = 10;
p_eAxC_cfg->bit_ccId = 8;
p_eAxC_cfg->bit_ruPortId = 0;
break;
}
default:
rte_panic("Incorrect Category\n");
}
}
if(p_s_cfg->xranCat == XRAN_CATEGORY_A)
p_s_cfg->numUlAxc = p_s_cfg->numAxc;
printf("bit_cuPortId %2d mask 0x%04x\n",p_eAxC_cfg->bit_cuPortId, p_eAxC_cfg->mask_cuPortId);
printf("bit_bandSectorId %2d mask 0x%04x\n",p_eAxC_cfg->bit_bandSectorId, p_eAxC_cfg->mask_bandSectorId);
printf("bit_ccId %2d mask 0x%04x\n",p_eAxC_cfg->bit_ccId, p_eAxC_cfg->mask_ccId);
printf("ruPortId %2d mask 0x%04x\n",p_eAxC_cfg->bit_ruPortId, p_eAxC_cfg->mask_ruPortId);
return 0;
}
int32_t
app_io_xran_fh_config_init(UsecaseConfig* p_use_cfg, RuntimeConfig* p_o_xu_cfg, struct xran_fh_init* p_xran_fh_init, struct xran_fh_config* p_xran_fh_cfg)
{
int32_t ret = 0;
int32_t i = 0;
int32_t o_xu_id = 0;
uint32_t nCenterFreq = 0;
struct xran_prb_map* pRbMap = NULL;
memset(p_xran_fh_cfg, 0, sizeof(struct xran_fh_config));
o_xu_id = p_o_xu_cfg->o_xu_id;
p_xran_fh_cfg->nDLRBs = app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number, p_o_xu_cfg->nDLBandwidth, p_o_xu_cfg->nDLAbsFrePointA);
p_xran_fh_cfg->nULRBs = app_xran_get_num_rbs(p_o_xu_cfg->xranTech, p_o_xu_cfg->mu_number, p_o_xu_cfg->nULBandwidth, p_o_xu_cfg->nULAbsFrePointA);
printf("FH init: nDLRBs %d, nULRBs %d\n", p_xran_fh_cfg->nDLRBs, p_xran_fh_cfg->nULRBs);
if(p_o_xu_cfg->DynamicSectionEna == 0){
pRbMap = p_o_xu_cfg->p_PrbMapDl;
pRbMap->dir = XRAN_DIR_DL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = p_xran_fh_cfg->nDLRBs;
pRbMap->prbMap[0].nBeamIndex = 0;
pRbMap->prbMap[0].compMethod = p_o_xu_cfg->compression == 0 ? XRAN_COMPMETHOD_NONE : XRAN_COMPMETHOD_BLKFLOAT;
pRbMap->prbMap[0].iqWidth = p_o_xu_cfg->compression == 0 ? 16 : p_o_xu_cfg->iqWidth;
pRbMap = p_o_xu_cfg->p_PrbMapUl;
pRbMap->dir = XRAN_DIR_UL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = p_xran_fh_cfg->nULRBs;
pRbMap->prbMap[0].nBeamIndex = 0;
pRbMap->prbMap[0].compMethod = p_o_xu_cfg->compression == 0 ? XRAN_COMPMETHOD_NONE : XRAN_COMPMETHOD_BLKFLOAT;
pRbMap->prbMap[0].iqWidth = p_o_xu_cfg->compression == 0 ? 16 : p_o_xu_cfg->iqWidth;
} else {
pRbMap = p_o_xu_cfg->p_PrbMapDl;
pRbMap->dir = XRAN_DIR_DL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
pRbMap = p_o_xu_cfg->p_PrbMapUl;
pRbMap->dir = XRAN_DIR_UL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
pRbMap = p_o_xu_cfg->p_PrbMapSrs;
pRbMap->dir = XRAN_DIR_UL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
}
p_xran_fh_cfg->sector_id = 0;
p_xran_fh_cfg->dpdk_port = o_xu_id;
p_xran_fh_cfg->nCC = p_o_xu_cfg->numCC;
p_xran_fh_cfg->neAxc = p_o_xu_cfg->numAxc;
p_xran_fh_cfg->neAxcUl = p_o_xu_cfg->numUlAxc;
p_xran_fh_cfg->nAntElmTRx = p_o_xu_cfg->antElmTRx;
p_xran_fh_cfg->frame_conf.nFrameDuplexType = p_o_xu_cfg->nFrameDuplexType;
p_xran_fh_cfg->frame_conf.nNumerology = p_o_xu_cfg->mu_number;
p_xran_fh_cfg->frame_conf.nTddPeriod = p_o_xu_cfg->nTddPeriod;
for (i = 0; i < p_o_xu_cfg->nTddPeriod; i++){
p_xran_fh_cfg->frame_conf.sSlotConfig[i] = p_o_xu_cfg->sSlotConfig[i];
}
p_xran_fh_cfg->prach_conf.nPrachSubcSpacing = p_o_xu_cfg->mu_number;
p_xran_fh_cfg->prach_conf.nPrachFreqStart = p_o_xu_cfg->prachOffset;
p_xran_fh_cfg->prach_conf.nPrachFilterIdx = p_o_xu_cfg->prachConfigIndex < 28 ? XRAN_FILTERINDEX_PRACH_012 : XRAN_FILTERINDEX_PRACH_ABC;
p_xran_fh_cfg->prach_conf.nPrachConfIdx = p_o_xu_cfg->prachConfigIndex;
p_xran_fh_cfg->prach_conf.nPrachFreqOffset = p_o_xu_cfg->prachFreqOffset;
p_xran_fh_cfg->srs_conf.symbMask = p_o_xu_cfg->srsSymMask;
p_xran_fh_cfg->srs_conf.eAxC_offset = 2 * p_o_xu_cfg->numAxc; /* PUSCH, PRACH, SRS */
p_xran_fh_cfg->ru_conf.xranTech = p_o_xu_cfg->xranTech;
p_xran_fh_cfg->ru_conf.xranCompHdrType = p_o_xu_cfg->CompHdrType;
p_xran_fh_cfg->ru_conf.xranCat = p_o_xu_cfg->xranCat;
p_xran_fh_cfg->ru_conf.iqWidth = p_o_xu_cfg->p_PrbMapDl->prbMap[0].iqWidth;
if (p_o_xu_cfg->compression == 0)
p_xran_fh_cfg->ru_conf.compMeth = XRAN_COMPMETHOD_NONE;
else
p_xran_fh_cfg->ru_conf.compMeth = XRAN_COMPMETHOD_BLKFLOAT;
p_xran_fh_cfg->ru_conf.compMeth_PRACH = p_o_xu_cfg->prachCompMethod;
if (p_o_xu_cfg->prachCompMethod == 0)
p_o_xu_cfg->prachiqWidth = 16;
p_xran_fh_cfg->ru_conf.iqWidth_PRACH = p_o_xu_cfg->prachiqWidth;
p_xran_fh_cfg->prach_eAxc_offset = p_o_xu_cfg->prach_eAxc_off;
printf("CompHdrType %s. iqWidth %d, compMeth %s, compMeth_PRACH %s, iqWidth_PRACH %d\n",
p_xran_fh_cfg->ru_conf.xranCompHdrType==1?"Static":"Dynamic",
p_xran_fh_cfg->ru_conf.iqWidth,
p_xran_fh_cfg->ru_conf.compMeth==XRAN_COMPMETHOD_NONE?"NONE":"BFP",
p_xran_fh_cfg->ru_conf.compMeth_PRACH==XRAN_COMPMETHOD_NONE?"PRACH NONE":"PRACH BFP",
p_xran_fh_cfg->ru_conf.iqWidth_PRACH);
p_xran_fh_cfg->ru_conf.fftSize = 0;
while (p_o_xu_cfg->nULFftSize >>= 1)
++p_xran_fh_cfg->ru_conf.fftSize;
p_xran_fh_cfg->ru_conf.byteOrder = (p_o_xu_cfg->nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER ;
p_xran_fh_cfg->ru_conf.iqOrder = (p_o_xu_cfg->iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER;
printf("FFT Order %d\n", p_xran_fh_cfg->ru_conf.fftSize);
nCenterFreq = p_o_xu_cfg->nDLAbsFrePointA + (((p_xran_fh_cfg->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(p_o_xu_cfg->mu_number));
p_xran_fh_cfg->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
printf("DL center freq %d DL NR-ARFCN %d\n", nCenterFreq, p_xran_fh_cfg->nDLCenterFreqARFCN);
nCenterFreq = p_o_xu_cfg->nULAbsFrePointA + (((p_xran_fh_cfg->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(p_o_xu_cfg->mu_number));
p_xran_fh_cfg->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
printf("UL center freq %d UL NR-ARFCN %d\n", nCenterFreq, p_xran_fh_cfg->nULCenterFreqARFCN);
p_xran_fh_cfg->bbdev_dec = NULL;
p_xran_fh_cfg->bbdev_enc = NULL;
p_xran_fh_cfg->log_level = 1;
p_xran_fh_cfg->max_sections_per_slot = RTE_MAX(p_o_xu_cfg->max_sections_per_slot, XRAN_MIN_SECTIONS_PER_SLOT);
p_xran_fh_cfg->max_sections_per_symbol = RTE_MAX(p_o_xu_cfg->max_sections_per_symbol, XRAN_MIN_SECTIONS_PER_SLOT);
printf("Max Sections: %d per symb %d per slot\n", p_xran_fh_cfg->max_sections_per_slot, p_xran_fh_cfg->max_sections_per_symbol);
if(p_o_xu_cfg->maxFrameId)
p_xran_fh_cfg->ru_conf.xran_max_frame = p_o_xu_cfg->maxFrameId;
p_xran_fh_cfg->Tadv_cp_dl = p_o_xu_cfg->Tadv_cp_dl;
p_xran_fh_cfg->T2a_min_cp_dl = p_o_xu_cfg->T2a_min_cp_dl;
p_xran_fh_cfg->T2a_max_cp_dl = p_o_xu_cfg->T2a_max_cp_dl;
p_xran_fh_cfg->T2a_min_cp_ul = p_o_xu_cfg->T2a_min_cp_ul;
p_xran_fh_cfg->T2a_max_cp_ul = p_o_xu_cfg->T2a_max_cp_ul;
p_xran_fh_cfg->T2a_min_up = p_o_xu_cfg->T2a_min_up;
p_xran_fh_cfg->T2a_max_up = p_o_xu_cfg->T2a_max_up;
p_xran_fh_cfg->Ta3_min = p_o_xu_cfg->Ta3_min;
p_xran_fh_cfg->Ta3_max = p_o_xu_cfg->Ta3_max;
p_xran_fh_cfg->T1a_min_cp_dl = p_o_xu_cfg->T1a_min_cp_dl;
p_xran_fh_cfg->T1a_max_cp_dl = p_o_xu_cfg->T1a_max_cp_dl;
p_xran_fh_cfg->T1a_min_cp_ul = p_o_xu_cfg->T1a_min_cp_ul;
p_xran_fh_cfg->T1a_max_cp_ul = p_o_xu_cfg->T1a_max_cp_ul;
p_xran_fh_cfg->T1a_min_up = p_o_xu_cfg->T1a_min_up;
p_xran_fh_cfg->T1a_max_up = p_o_xu_cfg->T1a_max_up;
p_xran_fh_cfg->Ta4_min = p_o_xu_cfg->Ta4_min;
p_xran_fh_cfg->Ta4_max = p_o_xu_cfg->Ta4_max;
p_xran_fh_cfg->enableCP = p_o_xu_cfg->enableCP;
p_xran_fh_cfg->prachEnable = p_o_xu_cfg->enablePrach;
p_xran_fh_cfg->srsEnable = p_o_xu_cfg->enableSrs;
p_xran_fh_cfg->puschMaskEnable = p_o_xu_cfg->puschMaskEnable;
p_xran_fh_cfg->puschMaskSlot = p_o_xu_cfg->puschMaskSlot;
p_xran_fh_cfg->debugStop = p_o_xu_cfg->debugStop;
p_xran_fh_cfg->debugStopCount = p_o_xu_cfg->debugStopCount;
p_xran_fh_cfg->DynamicSectionEna = p_o_xu_cfg->DynamicSectionEna;
p_xran_fh_cfg->GPS_Alpha = p_o_xu_cfg->GPS_Alpha;
p_xran_fh_cfg->GPS_Beta = p_o_xu_cfg->GPS_Beta;
p_xran_fh_cfg->cp_vlan_tag = p_o_xu_cfg->cp_vlan_tag;
p_xran_fh_cfg->up_vlan_tag = p_o_xu_cfg->up_vlan_tag;
return ret;
}
int32_t
app_io_xran_fh_init_init(UsecaseConfig* p_use_cfg, RuntimeConfig* p_o_xu_cfg, struct xran_fh_init* p_xran_fh_init)
{
int32_t ret = 0;
int32_t i = 0;
int32_t o_xu_id = 0;
int32_t pf_link_id = 0;
int32_t num_vfs_cu_p = 2;
void * ptr = NULL;
memset(p_xran_fh_init, 0, sizeof(struct xran_fh_init));
p_xran_fh_init->io_cfg.id = 0; /* O-DU */
p_xran_fh_init->io_cfg.core = p_use_cfg->io_core;
p_xran_fh_init->io_cfg.system_core = p_use_cfg->system_core;
p_xran_fh_init->io_cfg.pkt_proc_core = p_use_cfg->io_worker; /* do not start */
p_xran_fh_init->io_cfg.pkt_proc_core_64_127 = p_use_cfg->io_worker_64_127;
p_xran_fh_init->io_cfg.pkt_aux_core = 0; /* do not start*/
p_xran_fh_init->io_cfg.timing_core = p_use_cfg->io_core;
p_xran_fh_init->io_cfg.dpdkIoVaMode = p_use_cfg->iova_mode;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].initiator_en = p_use_cfg->owdmInitEn;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].measMethod = p_use_cfg->owdmMeasMeth;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].numberOfSamples = p_use_cfg->owdmNumSamps;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].filterType = p_use_cfg->owdmFltType;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].responseTo = p_use_cfg->owdmRspTo;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].measState = p_use_cfg->owdmMeasState;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].measId = p_use_cfg->owdmMeasId;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].owdm_enable = p_use_cfg->owdmEnable;
p_xran_fh_init->io_cfg.eowd_cmn[APP_O_DU].owdm_PlLength = p_use_cfg->owdmPlLength;
p_xran_fh_init->io_cfg.io_sleep = p_use_cfg->io_sleep;
p_xran_fh_init->io_cfg.dpdkMemorySize = p_use_cfg->dpdk_mem_sz;
p_xran_fh_init->io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
p_xran_fh_init->xran_ports = p_use_cfg->oXuNum;
p_xran_fh_init->io_cfg.nEthLinePerPort = p_use_cfg->EthLinesNumber;
p_xran_fh_init->io_cfg.nEthLineSpeed = p_use_cfg->EthLinkSpeed;
app_io_xran_eAxCid_conf_set(&p_xran_fh_init->eAxCId_conf, p_o_xu_cfg);
i = 0;
if(p_use_cfg->one_vf_cu_plane == 1){
num_vfs_cu_p = 1;
}
for(o_xu_id = 0; o_xu_id < p_use_cfg->oXuNum; o_xu_id++ ) { /* all O-XU */
for(pf_link_id = 0; pf_link_id < p_use_cfg->EthLinesNumber && pf_link_id < XRAN_ETH_PF_LINKS_NUM; pf_link_id++ ) { /* all PF ports for each O-XU */
if(num_vfs_cu_p*i < (XRAN_VF_MAX - 1)) {
p_xran_fh_init->io_cfg.dpdk_dev[num_vfs_cu_p*i] = &p_use_cfg->o_xu_pcie_bus_addr[o_xu_id][num_vfs_cu_p*pf_link_id][0]; /* U-Plane */
rte_ether_addr_copy(&p_use_cfg->remote_o_xu_addr[o_xu_id][num_vfs_cu_p*pf_link_id], &p_use_cfg->remote_o_xu_addr_copy[num_vfs_cu_p*i]);
printf("VF[%d] %s\n",num_vfs_cu_p*i, p_xran_fh_init->io_cfg.dpdk_dev[num_vfs_cu_p*i]);
if(p_use_cfg->one_vf_cu_plane == 0){
p_xran_fh_init->io_cfg.dpdk_dev[num_vfs_cu_p*i+1] = &p_use_cfg->o_xu_pcie_bus_addr[o_xu_id][num_vfs_cu_p*pf_link_id+1][0]; /* C-Plane */
rte_ether_addr_copy(&p_use_cfg->remote_o_xu_addr[o_xu_id][num_vfs_cu_p*pf_link_id+1], &p_use_cfg->remote_o_xu_addr_copy[num_vfs_cu_p*i+1]);
printf("VF[%d] %s\n",num_vfs_cu_p*i+1, p_xran_fh_init->io_cfg.dpdk_dev[num_vfs_cu_p*i+1]);
}
i++;
} else {
break;
}
}
}
p_xran_fh_init->io_cfg.one_vf_cu_plane = p_use_cfg->one_vf_cu_plane;
if(p_xran_fh_init->io_cfg.one_vf_cu_plane) {
p_use_cfg->num_vfs = i;
} else {
p_use_cfg->num_vfs = 2*i;
}
printf("p_use_cfg->num_vfs %d\n", p_use_cfg->num_vfs);
printf("p_use_cfg->num_rxq %d\n", p_use_cfg->num_rxq);
p_xran_fh_init->io_cfg.num_vfs = p_use_cfg->num_vfs;
p_xran_fh_init->io_cfg.num_rxq = p_use_cfg->num_rxq;
p_xran_fh_init->mtu = p_o_xu_cfg->mtu;
p_xran_fh_init->p_o_du_addr = (int8_t *)p_o_xu_cfg->o_du_addr;
p_xran_fh_init->p_o_ru_addr = (int8_t *)p_use_cfg->remote_o_xu_addr_copy;
snprintf(p_use_cfg->prefix_name, sizeof(p_use_cfg->prefix_name), "wls_%d",p_use_cfg->instance_id);
p_xran_fh_init->filePrefix = p_use_cfg->prefix_name;
p_xran_fh_init->totalBfWeights = p_o_xu_cfg->totalBfWeights;
for(o_xu_id = 0; o_xu_id < p_use_cfg->oXuNum && o_xu_id < XRAN_PORTS_NUM; o_xu_id++ ) { /* all O-XU */
if(p_o_xu_buff[o_xu_id] == NULL) {
ptr = _mm_malloc(sizeof(struct o_xu_buffers), 256);
if (ptr == NULL) {
rte_panic("_mm_malloc: Can't allocate %lu bytes\n", sizeof(struct o_xu_buffers));
}
p_o_xu_buff[o_xu_id] = (struct o_xu_buffers*)ptr;
}
p_o_xu_cfg->p_buff = p_o_xu_buff[o_xu_id];
p_o_xu_cfg++;
}
return ret;
}
int32_t
app_io_xran_buffers_max_sz_set (RuntimeConfig* p_o_xu_cfg)
{
......
......@@ -125,8 +125,6 @@ void app_io_xran_if_free(void);
struct xran_io_shared_ctrl * app_io_xran_if_ctrl_get(uint32_t o_xu_id);
int32_t app_io_xran_interface(uint32_t o_xu_id, RuntimeConfig *p_o_xu_cfg, UsecaseConfig* p_use_cfg);
int32_t app_io_xran_fh_config_init(UsecaseConfig* p_use_cfg, RuntimeConfig* p_o_xu_cfg, struct xran_fh_init* p_xran_fh_init, struct xran_fh_config* p_xran_fh_cfg);
int32_t app_io_xran_fh_init_init(UsecaseConfig* p_use_cfg, RuntimeConfig* p_o_xu_cfg, struct xran_fh_init* p_xran_fh_init);
int32_t app_io_xran_buffers_max_sz_set (RuntimeConfig* p_o_xu_cfg);
void app_io_xran_if_stop(void);
......
......@@ -123,218 +123,6 @@ uint32_t app_xran_get_tti_interval(uint8_t nMu)
return 0;
}
uint32_t app_xran_get_scs(uint8_t nMu)
{
if (nMu <= 3)
{
return nSubCarrierSpacing[nMu];
}
else
{
printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
}
return 0;
}
//-------------------------------------------------------------------------------------------
/** @ingroup group_nr5g_source_phy_common
*
* @param[in] nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz, 1: 30khz, 2: 60khz 3: 120khz, 4: 240khz
* @param[in] nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
* @param[in] nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
*
* @return Number of RBs in cell
*
* @description
* Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
*
**/
//-------------------------------------------------------------------------------------------
uint16_t app_xran_get_num_rbs(uint8_t ranTech, uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
{
uint32_t error = 1;
uint16_t numRBs = 0;
if (ranTech == XRAN_RAN_LTE) {
switch(nBandwidth)
{
case PHY_BW_5_0_MHZ:
numRBs = nLteNumRbsPerSymF1[nNumerology][0];
error = 0;
break;
case PHY_BW_10_0_MHZ:
numRBs = nLteNumRbsPerSymF1[nNumerology][1];
error = 0;
break;
case PHY_BW_15_0_MHZ:
numRBs = nLteNumRbsPerSymF1[nNumerology][2];
error = 0;
break;
case PHY_BW_20_0_MHZ:
numRBs = nLteNumRbsPerSymF1[nNumerology][3];
error = 0;
break;
default:
error = 1;
break;
}
} else if (nAbsFrePointA <= 6000000) {
// F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
if (nNumerology < 3)
{
switch(nBandwidth)
{
case PHY_BW_5_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][0];
error = 0;
break;
case PHY_BW_10_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][1];
error = 0;
break;
case PHY_BW_15_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][2];
error = 0;
break;
case PHY_BW_20_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][3];
error = 0;
break;
case PHY_BW_25_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][4];
error = 0;
break;
case PHY_BW_30_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][5];
error = 0;
break;
case PHY_BW_40_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][6];
error = 0;
break;
case PHY_BW_50_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][7];
error = 0;
break;
case PHY_BW_60_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][8];
error = 0;
break;
case PHY_BW_70_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][9];
error = 0;
break;
case PHY_BW_80_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][10];
error = 0;
break;
case PHY_BW_90_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][11];
error = 0;
break;
case PHY_BW_100_0_MHZ:
numRBs = nNumRbsPerSymF1[nNumerology][12];
error = 0;
break;
default:
error = 1;
break;
}
}
}
else
{
if ((nNumerology >= 2) && (nNumerology <= 3))
{
// F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
switch(nBandwidth)
{
case PHY_BW_50_0_MHZ:
numRBs = nNumRbsPerSymF2[nNumerology-2][0];
error = 0;
break;
case PHY_BW_100_0_MHZ:
numRBs = nNumRbsPerSymF2[nNumerology-2][1];
error = 0;
break;
case PHY_BW_200_0_MHZ:
numRBs = nNumRbsPerSymF2[nNumerology-2][2];
error = 0;
break;
case PHY_BW_400_0_MHZ:
numRBs = nNumRbsPerSymF2[nNumerology-2][3];
error = 0;
break;
default:
error = 1;
break;
}
}
}
if (error)
{
printf("ERROR: %s: RAN[%s] nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, (ranTech ? "LTE" : "5G NR"), nNumerology, nBandwidth, nAbsFrePointA);
}
else
{
printf("%s: RAN [%s] nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, (ranTech ? "LTE" : "5G NR"), nNumerology, nBandwidth, nAbsFrePointA, numRBs);
}
return numRBs;
}
//-------------------------------------------------------------------------------------------
/** @ingroup phy_cal_nrarfcn
*
* @param[in] center frequency
*
* @return NR-ARFCN
*
* @description
* This calculates NR-ARFCN value according to center frequency
*
**/
//-------------------------------------------------------------------------------------------
uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq)
{
uint32_t nDeltaFglobal,nFoffs,nNoffs;
uint32_t nNRARFCN = 0;
if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
{
nDeltaFglobal = 5;
nFoffs = 0;
nNoffs = 0;
}
else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
{
nDeltaFglobal = 15;
nFoffs = 3000*1000;
nNoffs = 600000;
}
else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
{
nDeltaFglobal = 60;
nFoffs = 24250080;
nNoffs = 2016667;
}
else
{
printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
return (0);
}
nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
return (nNRARFCN);
}
int32_t app_xran_slot_limit(int32_t nSfIdx)
{
......
......@@ -136,9 +136,6 @@ void sys_save_buf_to_file_txt(char *filename, char *bufname, unsigned char *pBuf
void sys_save_buf_to_file(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
int sys_load_file_to_buff(char *filename, char *bufname, unsigned char *pBuffer, unsigned int size, unsigned int buffers_num);
uint32_t app_xran_get_scs(uint8_t nMu);
uint16_t app_xran_get_num_rbs(uint8_t ranTech, uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA);
uint32_t app_xran_cal_nrarfcn(uint32_t nCenterFreq);
int32_t app_xran_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType,
uint32_t nTddPeriod, struct xran_slot_config *psSlotConfig);
uint32_t app_xran_get_tti_interval(uint8_t nMu);
......
......@@ -20,8 +20,10 @@
*/
#include "oran-config.h"
#include "common/utils/assertions.h"
#include "xran_fh_o_du.h"
#include "rte_ether.h"
#include "stdio.h"
......@@ -421,3 +423,229 @@ void print_fh_config(const struct xran_fh_config *fh_config)
fh_config->max_sections_per_slot,
fh_config->max_sections_per_symbol);
}
static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg)
{
io_cfg->id = 0; // 0 = O-DU
io_cfg->num_vfs = 2; // 2 VFS for C/U-plane
io_cfg->num_rxq = 2; // 2 RX queues
io_cfg->dpdk_dev[0] = strdup("0000:31:06.0");
io_cfg->dpdk_dev[1] = strdup("0000:31:06.1");
//io_cfg->bbdev_dev = NULL;
io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // none
io_cfg->dpdkIoVaMode = 0; // IOVA mode */
io_cfg->dpdkMemorySize = 0; /* DPDK memory size */
io_cfg->core = 4; /* sample app: equal to io_core */
io_cfg->system_core = 0;
io_cfg->pkt_proc_core = 0x4; // bitmap 0b100 -> core 2
io_cfg->pkt_proc_core_64_127 = 0x0; // bitmap 0 -> no core
io_cfg->pkt_aux_core = 0; /* sapmle app says 0 = "do not start" */
io_cfg->timing_core = 4; /* sample app: equal to io_core */
//io_cfg->port = {0}; // all 0
io_cfg->io_sleep = 0; // no sleep
io_cfg->nEthLinePerPort = 1; // 1 link
io_cfg->nEthLineSpeed = 10; // 10G
io_cfg->one_vf_cu_plane = 0; // false: C/U-plane don't share VF
// io_cfg->eowd_cmn[0] // all 0
// io_cfg->eowd_cmn[1] // all 0
// io_cfg->eowd_port[0]... // all 0
return true;
}
static bool set_fh_eaxcid_conf(struct xran_eaxcid_config *eaxcid_conf, enum xran_category cat)
{
// values taken from sample app
switch (cat) {
case XRAN_CATEGORY_A:
eaxcid_conf->mask_cuPortId = 0xf000;
eaxcid_conf->mask_bandSectorId = 0x0f00;
eaxcid_conf->mask_ccId = 0x00f0;
eaxcid_conf->mask_ruPortId = 0x000f;
eaxcid_conf->bit_cuPortId = 12;
eaxcid_conf->bit_bandSectorId = 8;
eaxcid_conf->bit_ccId = 4;
eaxcid_conf->bit_ruPortId = 0;
break;
case XRAN_CATEGORY_B:
eaxcid_conf->mask_cuPortId = 0xf000;
eaxcid_conf->mask_bandSectorId = 0x0c00;
eaxcid_conf->mask_ccId = 0x0300;
eaxcid_conf->mask_ruPortId = 0x000f;
eaxcid_conf->bit_cuPortId = 12;
eaxcid_conf->bit_bandSectorId = 10;
eaxcid_conf->bit_ccId = 8;
eaxcid_conf->bit_ruPortId = 0;
break;
default:
return false;
}
return true;
}
int8_t *get_ether_addr(const uint8_t addr[6])
{
struct rte_ether_addr *ether_addr = malloc(sizeof(*ether_addr));
AssertFatal(ether_addr != NULL, "out of memory\n");
for (int i = 0; i < 6; ++i)
ether_addr->addr_bytes[i] = addr[i];
return (int8_t *)ether_addr;
}
bool set_fh_init(struct xran_fh_init *fh_init)
{
memset(fh_init, 0, sizeof(*fh_init));
if (!set_fh_io_cfg(&fh_init->io_cfg))
return false;
if (!set_fh_eaxcid_conf(&fh_init->eAxCId_conf, XRAN_CATEGORY_A))
return false;
fh_init->xran_ports = 1;
fh_init->dpdkBasebandFecMode = 0;
fh_init->dpdkBasebandDevice = NULL;
fh_init->filePrefix = strdup("wls_0");
fh_init->mtu = 1500;
fh_init->p_o_du_addr = get_ether_addr((uint8_t[6]) {0x00, 0x11, 0x22, 0x33, 0x44, 0x99});
fh_init->p_o_ru_addr = get_ether_addr((uint8_t[6]) {0xe8, 0xc7, 0x4f, 0x1e, 0xc7, 0x11});
fh_init->totalBfWeights = 32;
return true;
}
static bool set_fh_prach_config(struct xran_prach_config *prach_config)
{
prach_config->nPrachConfIdx = 159;
prach_config->nPrachSubcSpacing = 1;
prach_config->nPrachZeroCorrConf = 0;
prach_config->nPrachRestrictSet = 0;
prach_config->nPrachRootSeqIdx = 0;
prach_config->nPrachFreqStart = 22;
prach_config->nPrachFreqOffset = -2732;
prach_config->nPrachFilterIdx = 3;
prach_config->startSymId = 0;
prach_config->lastSymId = 0;
prach_config->startPrbc = 0;
prach_config->numPrbc = 0;
prach_config->timeOffset = 0;
prach_config->freqOffset = 0;
prach_config->eAxC_offset = 0;
return true;
}
static bool set_fh_srs_config(struct xran_srs_config *srs_config)
{
srs_config->symbMask = 0;
srs_config->eAxC_offset = 8;
return true;
}
static bool set_fh_frame_config(struct xran_frame_config *frame_config)
{
frame_config->nFrameDuplexType = 1; // 0: FDD, 1: TDD
frame_config->nNumerology = 1;
frame_config->nTddPeriod = 5;
#define D 0
#define U 1
#define G 2
frame_config->sSlotConfig[0] = (struct xran_slot_config){.nSymbolType = {D, D, D, D, D, D, D, D, D, D, D, D, D, D}};
frame_config->sSlotConfig[1] = (struct xran_slot_config){.nSymbolType = {D, D, D, D, D, D, D, D, D, D, D, D, D, D}};
frame_config->sSlotConfig[2] = (struct xran_slot_config){.nSymbolType = {D, D, D, D, D, D, D, D, D, D, D, D, D, D}};
frame_config->sSlotConfig[3] = (struct xran_slot_config){.nSymbolType = {D, D, D, D, D, D, G, G, G, G, U, U, U, U}};
frame_config->sSlotConfig[4] = (struct xran_slot_config){.nSymbolType = {U, U, U, U, U, U, U, U, U, U, U, U, U, U}};
#undef D
#undef U
#undef G
return true;
}
static bool set_fh_ru_config(struct xran_ru_config *ru_config)
{
ru_config->xranTech = XRAN_RAN_5GNR;
ru_config->xranCat = XRAN_CATEGORY_A;
ru_config->xranCompHdrType = XRAN_COMP_HDR_TYPE_STATIC;
ru_config->iqWidth = 9;
ru_config->compMeth = XRAN_COMPMETHOD_BLKFLOAT;
ru_config->iqWidth_PRACH = 9;
ru_config->compMeth_PRACH = XRAN_COMPMETHOD_BLKFLOAT;
ru_config->fftSize = 12;
ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER;
ru_config->iqOrder = XRAN_I_Q_ORDER;
ru_config->xran_max_frame = 0;
return true;
}
bool set_fh_config(struct xran_fh_config *fh_config)
{
memset(fh_config, 0, sizeof(*fh_config));
fh_config->dpdk_port = 0;
fh_config->sector_id = 0;
fh_config->nCC = 1;
fh_config->neAxc = 4;
fh_config->neAxcUl = 4;
fh_config->nAntElmTRx = 4;
fh_config->nDLFftSize = 0;
fh_config->nULFftSize = 0;
fh_config->nDLRBs = 273;
fh_config->nULRBs = 273;
fh_config->nDLAbsFrePointA = 0;
fh_config->nULAbsFrePointA = 0;
fh_config->nDLCenterFreqARFCN = 630048;
fh_config->nULCenterFreqARFCN = 630048;
fh_config->ttiCb = NULL;
fh_config->ttiCbParam = NULL;
fh_config->Tadv_cp_dl = 125;
fh_config->T2a_min_cp_dl = 285;
fh_config->T2a_max_cp_dl = 429;
fh_config->T2a_min_cp_ul = 285;
fh_config->T2a_max_cp_ul = 429;
fh_config->T2a_min_up = 125;
fh_config->T2a_max_up = 428;
fh_config->Ta3_min = 130;
fh_config->Ta3_max = 170;
fh_config->T1a_min_cp_dl = 285;
fh_config->T1a_max_cp_dl = 429;
fh_config->T1a_min_cp_ul = 285;
fh_config->T1a_max_cp_ul = 429;
fh_config->T1a_min_up = 96;
fh_config->T1a_max_up = 196;
fh_config->Ta4_min = 110;
fh_config->Ta4_max = 180;
fh_config->enableCP = 1;
fh_config->prachEnable = 1;
fh_config->srsEnable = 0;
fh_config->puschMaskEnable = 0;
fh_config->puschMaskSlot = 0;
fh_config->cp_vlan_tag = 53;
fh_config->up_vlan_tag = 53;
fh_config->debugStop = 0;
fh_config->debugStopCount = 0;
fh_config->DynamicSectionEna = 0;
fh_config->GPS_Alpha = 0;
fh_config->GPS_Beta = 0;
if (!set_fh_prach_config(&fh_config->prach_conf))
return false;
if (!set_fh_srs_config(&fh_config->srs_conf))
return false;
if (!set_fh_frame_config(&fh_config->frame_conf))
return false;
if (!set_fh_ru_config(&fh_config->ru_conf))
return false;
fh_config->bbdev_enc = NULL;
fh_config->bbdev_dec = NULL;
// fh_config->tx_cp_eAxC2Vf [not implemented by fhi_lib]
// fh_config->tx_up_eAxC2Vf [not implemented by fhi_lib]
// fh_config->rx_cp_eAxC2Vf [not implemented by fhi_lib]
// fh_config->rx_up_eAxC2Vf [not implemented by fhi_lib]
fh_config->log_level = 1;
fh_config->max_sections_per_slot = 8;
fh_config->max_sections_per_symbol = 8;
return true;
}
......@@ -22,9 +22,14 @@
#ifndef ORAN_CONFIG_H
#define ORAN_CONFIG_H
#include "stdbool.h"
struct xran_fh_init;
void print_fh_init(const struct xran_fh_init *fh_init);
struct xran_fh_config;
void print_fh_config(const struct xran_fh_config *fh_config);
bool set_fh_init(struct xran_fh_init *fh_init);
bool set_fh_config(struct xran_fh_config *fh_config);
#endif /* ORAN_CONFIG_H */
......@@ -496,6 +496,48 @@ app_alloc_all_cfgs(void)
return 0;
}
static void setup_vrbmap(RuntimeConfig* p_o_xu_cfg, const struct xran_fh_config* p_xran_fh_cfg)
{
struct xran_prb_map* pRbMap = NULL;
assert(p_o_xu_cfg->DynamicSectionEna == 0);
pRbMap = p_o_xu_cfg->p_PrbMapDl;
pRbMap->dir = XRAN_DIR_DL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = p_xran_fh_cfg->nDLRBs;
pRbMap->prbMap[0].nBeamIndex = 0;
pRbMap->prbMap[0].compMethod = p_o_xu_cfg->compression == 0 ? XRAN_COMPMETHOD_NONE : XRAN_COMPMETHOD_BLKFLOAT;
pRbMap->prbMap[0].iqWidth = p_o_xu_cfg->compression == 0 ? 16 : p_o_xu_cfg->iqWidth;
pRbMap = p_o_xu_cfg->p_PrbMapUl;
pRbMap->dir = XRAN_DIR_UL;
pRbMap->xran_port = 0;
pRbMap->band_id = 0;
pRbMap->cc_id = 0;
pRbMap->ru_port_id = 0;
pRbMap->tti_id = 0;
pRbMap->start_sym_id = 0;
pRbMap->nPrbElm = 1;
pRbMap->prbMap[0].nStartSymb = 0;
pRbMap->prbMap[0].numSymb = 14;
pRbMap->prbMap[0].nRBStart = 0;
pRbMap->prbMap[0].nRBSize = p_xran_fh_cfg->nULRBs;
pRbMap->prbMap[0].nBeamIndex = 0;
pRbMap->prbMap[0].compMethod = p_o_xu_cfg->compression == 0 ? XRAN_COMPMETHOD_NONE : XRAN_COMPMETHOD_BLKFLOAT;
pRbMap->prbMap[0].iqWidth = p_o_xu_cfg->compression == 0 ? 16 : p_o_xu_cfg->iqWidth;
}
// to be removed
extern int oai_physide_dl_tti_call_back(void * param);
int *oai_main(int argc, char *argv[])
......@@ -541,9 +583,8 @@ int *oai_main(int argc, char *argv[])
app_io_xran_if_alloc();
/* one init for all O-XU */
app_io_xran_fh_init_init(p_usecaseConfiguration, p_startupConfiguration[0], &app_io_xran_fh_init);
if (!set_fh_init(&app_io_xran_fh_init))
exit(123);
print_fh_init(&app_io_xran_fh_init);
xret = xran_init(argc, argv, &app_io_xran_fh_init, argv[0], &app_io_xran_handle);
......@@ -582,10 +623,13 @@ int *oai_main(int argc, char *argv[])
printf("Numm CC %d numAxc %d numUlAxc %d\n", p_o_xu_cfg->numCC, p_o_xu_cfg->numAxc, p_o_xu_cfg->numUlAxc);
app_io_xran_fh_config_init(p_usecaseConfiguration, p_o_xu_cfg, &app_io_xran_fh_init, &app_io_xran_fh_config[o_xu_id]);
if (!set_fh_config(&app_io_xran_fh_config[o_xu_id]))
exit(124);
print_fh_config(&app_io_xran_fh_config[o_xu_id]);
// only needed for setting up buffers, remove
setup_vrbmap(p_o_xu_cfg, &app_io_xran_fh_config[o_xu_id]);
xret = xran_open(app_io_xran_handle, &app_io_xran_fh_config[o_xu_id]);
if(xret != XRAN_STATUS_SUCCESS){
printf("xran_open failed %d\n", xret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment