1 /******************************************************************************
3 * Copyright (c) 2020 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 *******************************************************************************/
20 * @brief This module provides implementation of BBU tasks for sample app
23 * @author Intel Corporation
33 #include <immintrin.h>
36 #include "app_bbu_pool.h"
37 #include "app_io_fh_xran.h"
38 #include "xran_compression.h"
39 #include "xran_cp_api.h"
40 #include "xran_fh_o_du.h"
41 #include "xran_mlog_task_id.h"
43 extern RuntimeConfig* p_startupConfiguration[XRAN_PORTS_NUM];
44 static SampleSplitStruct gsDlPostSymbolTaskSplit[MAX_PHY_INSTANCES][MAX_NUM_OF_SF_5G_CTX][MAX_TEST_SPLIT_NUM];
45 static SampleSplitStruct gsDlCfgAxCTaskSplit[MAX_PHY_INSTANCES][MAX_NUM_OF_SF_5G_CTX][MAX_TEST_SPLIT_NUM];
47 void app_bbu_pool_pre_task_dl_post(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara)
49 int32_t nSplitGroup = 0;
51 uint32_t nSfIdx = get_dl_sf_idx(nSubframe, nCellIdx);
52 uint32_t nCtxNum = get_dl_sf_ctx(nSfIdx, nCellIdx);
53 SampleSplitStruct *pTaskSplitPara;
54 int32_t nGroupNum = 0;
55 int32_t nSymbStart = 0, nSymbPerSplit = 0;
56 int32_t nTotalLayers = 0, nLayerStart = 0, nLayerPerSplit = 0;
57 struct bbu_xran_io_if *psXranIoIf = app_io_xran_if_get();
58 struct xran_fh_config* pXranConf = NULL;
59 // struct xran_io_shared_ctrl *psIoCtrl = NULL;
60 uint32_t nRuCcidx = 0;
61 int32_t xran_port = 0;
63 if(psXranIoIf == NULL)
64 rte_panic("psXranIoIf == NULL");
66 if(nCellIdx >= MAX_PHY_INSTANCES)
67 rte_panic("nCellIdx >= MAX_PHY_INSTANCES");
69 xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
72 printf("incorrect xran_port\n");
73 return /*EBBUPOOL_CORRECT*/;
76 // psIoCtrl = app_io_xran_if_ctrl_get(xran_port);
77 pXranConf = &app_io_xran_fh_config[xran_port];
79 rte_panic("pXranConf");
81 nTotalLayers = pXranConf->neAxc;
82 nSplitGroup = pXranConf->neAxc;
84 /* all symp per eAxC */
86 // nTotalSymb = XRAN_NUM_OF_SYMBOL_PER_SLOT;
87 nSymbPerSplit = XRAN_NUM_OF_SYMBOL_PER_SLOT;
89 nLayerPerSplit = nTotalLayers/nSplitGroup;
91 pPara->nTaskNum = nSplitGroup;
92 for (iTask = 0; iTask < (nSplitGroup-1) && iTask < (MAX_TEST_SPLIT_NUM-1); iTask ++)
94 pTaskSplitPara = &(gsDlPostSymbolTaskSplit[nCellIdx][nCtxNum][iTask]);
95 pTaskSplitPara->nSymbStart = nSymbStart;
96 pTaskSplitPara->nSymbNum = nSymbPerSplit;
97 pTaskSplitPara->eSplitType = LAYER_SPLIT;
98 pTaskSplitPara->nSplitIndex = iTask;
99 pTaskSplitPara->nGroupStart = 0;
100 pTaskSplitPara->nGroupNum = nGroupNum;
101 pTaskSplitPara->nLayerStart = nLayerStart;
102 pTaskSplitPara->nLayerNum = nLayerPerSplit;
103 pPara->pTaskExePara[iTask] = pTaskSplitPara;
104 //nSymbStart += nSymbPerSplit;
105 nLayerStart += nLayerPerSplit;
108 pTaskSplitPara = &(gsDlPostSymbolTaskSplit[nCellIdx][nCtxNum][iTask]);
109 pTaskSplitPara->nSymbStart = nSymbStart;
110 pTaskSplitPara->nSymbNum = nSymbPerSplit;
111 pTaskSplitPara->eSplitType = LAYER_SPLIT;
112 pTaskSplitPara->nSplitIndex = iTask;
113 pTaskSplitPara->nGroupStart = 0;
114 pTaskSplitPara->nGroupNum = nGroupNum;
115 pTaskSplitPara->nLayerStart = nLayerStart;
116 pTaskSplitPara->nLayerNum = nTotalLayers - nLayerStart;
117 pPara->pTaskExePara[iTask] = pTaskSplitPara;
122 void app_bbu_pool_pre_task_dl_cfg(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara)
124 int32_t nSplitGroup = 0;
126 uint32_t nSfIdx = get_dl_sf_idx(nSubframe, nCellIdx);
127 uint32_t nCtxNum = get_dl_sf_ctx(nSfIdx, nCellIdx);
128 SampleSplitStruct *pTaskSplitPara;
129 int32_t nGroupNum = 0;
130 int32_t nSymbStart = 0, nSymbPerSplit = 0;
131 int32_t nTotalLayers = 0, nLayerStart = 0, nLayerPerSplit = 0;
132 struct bbu_xran_io_if *psXranIoIf = app_io_xran_if_get();
133 struct xran_fh_config* pXranConf = NULL;
134 // struct xran_io_shared_ctrl *psIoCtrl = NULL;
135 uint32_t nRuCcidx = 0;
136 int32_t xran_port = 0;
139 if(psXranIoIf == NULL)
140 rte_panic("psXranIoIf == NULL");
142 if(nCellIdx >= MAX_PHY_INSTANCES)
143 rte_panic("nCellIdx >= MAX_PHY_INSTANCES");
145 xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
148 printf("incorrect xran_port\n");
149 return /*EBBUPOOL_CORRECT*/;
152 // psIoCtrl = app_io_xran_if_ctrl_get(xran_port);
153 pXranConf = &app_io_xran_fh_config[xran_port];
154 if(pXranConf == NULL)
155 rte_panic("pXranConf");
157 pXranConf = &app_io_xran_fh_config[xran_port];
158 if(pXranConf == NULL)
159 rte_panic("pXranConf");
161 if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_A){
162 neAxc = pXranConf->neAxc;
164 } else if (pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B) {
165 neAxc = pXranConf->neAxc;
170 nTotalLayers = neAxc;
172 /* all symb per eAxC */
174 nSymbPerSplit = XRAN_NUM_OF_SYMBOL_PER_SLOT;
176 nLayerPerSplit = nTotalLayers/nSplitGroup;
178 pPara->nTaskNum = nSplitGroup;
179 for (iTask = 0; iTask < (nSplitGroup-1) && iTask < (MAX_TEST_SPLIT_NUM-1); iTask ++)
181 pTaskSplitPara = &(gsDlCfgAxCTaskSplit[nCellIdx][nCtxNum][iTask]);
182 pTaskSplitPara->nSymbStart = nSymbStart;
183 pTaskSplitPara->nSymbNum = nSymbPerSplit;
184 pTaskSplitPara->eSplitType = LAYER_SPLIT;
185 pTaskSplitPara->nSplitIndex = iTask;
186 pTaskSplitPara->nGroupStart = 0;
187 pTaskSplitPara->nGroupNum = nGroupNum;
188 pTaskSplitPara->nLayerStart = nLayerStart;
189 pTaskSplitPara->nLayerNum = nLayerPerSplit;
190 pPara->pTaskExePara[iTask] = pTaskSplitPara;
191 //nSymbStart += nSymbPerSplit;
192 nLayerStart += nLayerPerSplit;
195 pTaskSplitPara = &(gsDlCfgAxCTaskSplit[nCellIdx][nCtxNum][iTask]);
196 pTaskSplitPara->nSymbStart = nSymbStart;
197 pTaskSplitPara->nSymbNum = nSymbPerSplit;
198 pTaskSplitPara->eSplitType = LAYER_SPLIT;
199 pTaskSplitPara->nSplitIndex = iTask;
200 pTaskSplitPara->nGroupStart = 0;
201 pTaskSplitPara->nGroupNum = nGroupNum;
202 pTaskSplitPara->nLayerStart = nLayerStart;
203 pTaskSplitPara->nLayerNum = nTotalLayers - nLayerStart;
204 pPara->pTaskExePara[iTask] = pTaskSplitPara;
209 //-------------------------------------------------------------------------------------------
212 * @param[in] pCookies task input parameter
213 * @return 0 if SUCCESS
216 * This function takes the DL Config from MAC and stores it into PHY Internal structures.
217 * and initials the parameter of UL DCI.
220 //-------------------------------------------------------------------------------------------
222 app_bbu_pool_task_dl_config(void *pCookies)
224 EventCtrlStruct *pEventCtrl = (EventCtrlStruct *)pCookies;
225 uint16_t nCellIdx = pEventCtrl->nCellIdx;
226 uint32_t nSfIdx = get_dl_sf_idx(pEventCtrl->nSlotIdx, nCellIdx);
227 uint32_t nCtxNum = get_dl_sf_ctx(nSfIdx, nCellIdx);
228 uint32_t mlogVariablesCnt, mlogVariables[50];
229 uint64_t mlog_start = MLogTick();
230 uint32_t nRuCcidx = 0;
231 int32_t xran_port = 0;
232 SampleSplitStruct *pTaskPara = (SampleSplitStruct*)pEventCtrl->pTaskPara;
233 struct bbu_xran_io_if *psXranIoIf = app_io_xran_if_get();
234 struct xran_fh_config* pXranConf = NULL;
235 xran_status_t status;
236 struct xran_io_shared_ctrl *psIoCtrl = NULL;
237 int32_t cc_id, ant_id, sym_id, tti;
239 struct o_xu_buffers * p_iq = NULL;
240 int32_t nSymbMask = 0b11111111111111;
241 RuntimeConfig *p_o_xu_cfg = NULL;
242 uint16_t nLayerStart = 0, nLayer = 0;
244 if(psXranIoIf == NULL)
245 rte_panic("psXranIoIf == NULL");
247 xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
250 printf("incorrect xran_port\n");
251 return EBBUPOOL_CORRECT;
253 psIoCtrl = app_io_xran_if_ctrl_get(xran_port);
254 pXranConf = &app_io_xran_fh_config[xran_port];
255 if(pXranConf == NULL)
256 rte_panic("pXranConf");
258 mlogVariablesCnt = 0;
259 mlogVariables[mlogVariablesCnt++] = 0xCCBBCCBB;
260 mlogVariables[mlogVariablesCnt++] = pEventCtrl->nSlotIdx;
261 mlogVariables[mlogVariablesCnt++] = 0;
262 mlogVariables[mlogVariablesCnt++] = nCellIdx;
263 mlogVariables[mlogVariablesCnt++] = nSfIdx;
264 mlogVariables[mlogVariablesCnt++] = nCtxNum;
265 mlogVariables[mlogVariablesCnt++] = xran_port;
266 mlogVariables[mlogVariablesCnt++] = nRuCcidx;
268 p_o_xu_cfg = p_startupConfiguration[xran_port];
271 mlog_start = MLogTick();
273 if(LAYER_SPLIT == pTaskPara->eSplitType) {
274 // iSplit = pTaskPara->nSplitIndex;
275 nLayerStart = pTaskPara->nLayerStart;
276 nLayer = pTaskPara->nLayerNum;
277 //printf("\nsf %d nSymbStart %d nSymb %d iSplit %d", nSfIdx, nSymbStart, nSymb, iSplit);
279 rte_panic("LAYER_SPLIT == pTaskPara->eSplitType");
282 if(p_o_xu_cfg->p_buff) {
283 p_iq = p_o_xu_cfg->p_buff;
285 rte_panic("Error p_o_xu_cfg->p_buff\n");
288 for(cc_id = nRuCcidx; cc_id < psXranIoIf->num_cc_per_port[xran_port]; cc_id++) {
289 if (cc_id >= XRAN_MAX_SECTOR_NR)
291 rte_panic("cell id %d exceeding max number", cc_id);
293 for(ant_id = nLayerStart; ant_id < (nLayerStart + nLayer); ant_id++) {
294 if(p_o_xu_cfg->appMode == APP_O_DU) {
295 flowId = p_o_xu_cfg->numAxc * cc_id + ant_id;
297 flowId = p_o_xu_cfg->numUlAxc * cc_id + ant_id;
299 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
300 if(((1 << sym_id) & nSymbMask)) {
301 if ((status = app_io_xran_iq_content_init_cp_tx(p_o_xu_cfg->appMode, pXranConf,
302 psXranIoIf, psIoCtrl, p_iq,
303 cc_id, ant_id, sym_id, tti, flowId)) != 0) {
304 rte_panic("app_io_xran_iq_content_init_cp_tx");
311 xran_prepare_cp_dl_slot(xran_port, nSfIdx, nRuCcidx, /*psXranIoIf->num_cc_per_port[xran_port]*/ 1, nSymbMask, nLayerStart,
312 nLayer, 0, XRAN_NUM_OF_SYMBOL_PER_SLOT);
314 if (mlogVariablesCnt)
315 MLogAddVariables((uint32_t)mlogVariablesCnt, (uint32_t *)mlogVariables, mlog_start);
317 //unlock the next task
318 next_event_unlock(pCookies);
319 MLogTask(PCID_GNB_DL_CFG_CC0+nCellIdx, mlog_start, MLogTick());
321 return EBBUPOOL_CORRECT;
325 app_io_xran_dl_pack_func(uint16_t nCellIdx, uint32_t nSfIdx, uint32_t nSymMask,
326 uint32_t nAntStart, uint32_t nAntNum, uint32_t nSymStart, uint32_t nSymNum)
328 xran_status_t status;
329 uint32_t nSlotIdx = get_dl_sf_idx(nSfIdx, nCellIdx);
330 // struct xran_io_shared_ctrl * psBbuXranIo = NULL;
331 struct bbu_xran_io_if *psXranIoIf = app_io_xran_if_get();
332 int32_t xran_port = 0;
333 uint32_t nRuCcidx = 0;
334 struct o_xu_buffers * p_iq = NULL;
335 RuntimeConfig *p_o_xu_cfg = NULL;
337 struct xran_fh_config *pXranConf = NULL;
338 int32_t cc_id, ant_id, sym_id, tti;
339 struct xran_io_shared_ctrl *psIoCtrl = NULL;
341 xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
345 printf("incorrect xran_port\n");
349 psIoCtrl = app_io_xran_if_ctrl_get(xran_port);
351 if(psIoCtrl == NULL) {
352 printf("psIoCtrl == NULL\n");
356 p_o_xu_cfg = p_startupConfiguration[xran_port];
357 if(p_o_xu_cfg == NULL) {
358 printf("p_o_xu_cfg == NULL\n");
362 if(p_o_xu_cfg->p_buff) {
363 p_iq = p_o_xu_cfg->p_buff;
365 rte_panic("Error p_o_xu_cfg->p_buff\n");
368 pXranConf = &app_io_xran_fh_config[xran_port];
371 for(cc_id = nRuCcidx; cc_id < psXranIoIf->num_cc_per_port[xran_port]; cc_id++) {
372 for(ant_id = nAntStart; ant_id < (nAntStart + nAntNum) && ant_id < pXranConf->neAxc; ant_id++) {
373 if(p_o_xu_cfg->appMode == APP_O_DU) {
374 flowId = p_o_xu_cfg->numAxc * cc_id + ant_id;
376 flowId = p_o_xu_cfg->numUlAxc * cc_id + ant_id;
378 for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
379 if(((1 << sym_id) & nSymMask)) {
380 if ((status = app_io_xran_iq_content_init_up_tx(p_o_xu_cfg->appMode, pXranConf,
381 psXranIoIf, psIoCtrl, p_iq,
382 cc_id, ant_id, sym_id, tti, flowId)) != 0) {
383 rte_panic("app_io_xran_iq_content_init_up_tx");
390 xran_prepare_up_dl_sym(xran_port, nSlotIdx, nRuCcidx, 1, nSymMask, nAntStart, nAntNum, nSymStart, nSymNum);
395 app_io_xran_dl_post_func(uint16_t nCellIdx, uint32_t nSfIdx, uint32_t nSymMask, uint32_t nAntStart, uint32_t nAntNum)
397 uint16_t phyInstance = nCellIdx;
398 // uint32_t Ntx_antennas;
399 uint16_t nOranCellIdx;
401 uint64_t tTotal = MLogTick();
402 // struct xran_io_shared_ctrl * psBbuXranIo = NULL;
403 struct bbu_xran_io_if *psXranIoIf = app_io_xran_if_get();
404 int32_t xran_port = 0;
405 uint32_t nRuCcidx = 0;
406 // struct xran_fh_config *pXranConf = NULL;
408 nSymMask = nSymMask + 0;
410 nOranCellIdx = nCellIdx;
411 xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nOranCellIdx, &nRuCcidx);
413 printf("incorrect xran_port\n");
417 // pXranConf = &app_io_xran_fh_config[xran_port];
418 // Ntx_antennas = pXranConf->neAxc;
420 app_io_xran_dl_pack_func(nCellIdx, nSfIdx, nSymMask, nAntStart, nAntNum, 0, XRAN_NUM_OF_SYMBOL_PER_SLOT);
422 MLogTask(PCID_GNB_DL_IQ_COMPRESS_CC0 + phyInstance, tTotal, MLogTick());
427 //-------------------------------------------------------------------------------------------
428 /** @ingroup group_nr5g_source_phy_pdsch
430 * @param[in] pCookies task input parameter
431 * @return 0 if SUCCESS
434 * This function will reset phy dl buffers.
437 //-------------------------------------------------------------------------------------------
438 int32_t app_bbu_pool_task_dl_post(void *pCookies)
440 EventCtrlStruct *pEventCtrl = (EventCtrlStruct *)pCookies;
441 uint16_t nCellIdx = pEventCtrl->nCellIdx;
442 uint32_t nSfIdx = get_dl_sf_idx(pEventCtrl->nSlotIdx, nCellIdx);
443 SampleSplitStruct *pTaskPara = (SampleSplitStruct*)pEventCtrl->pTaskPara;
444 uint16_t nSymbStart = 0, nSymb = 0, iOfdmSymb = 0, iSplit = 0;
445 uint32_t nSymMask = 0;
447 uint32_t mlogVar[10];
448 uint32_t mlogVarCnt = 0;
449 uint16_t nLayerStart = 0, nLayer = 0;
450 mlog_start = MLogTick();
452 if(LAYER_SPLIT == pTaskPara->eSplitType) {
453 nSymbStart = pTaskPara->nSymbStart;
454 nSymb = pTaskPara->nSymbNum;
455 iSplit = pTaskPara->nSplitIndex;
456 nLayerStart = pTaskPara->nLayerStart;
457 nLayer = pTaskPara->nLayerNum;
458 //printf("\nsf %d nSymbStart %d nSymb %d iSplit %d", nSfIdx, nSymbStart, nSymb, iSplit);
459 } else if(OFDM_SYMB_SPLIT == pTaskPara->eSplitType) {
460 nSymbStart = pTaskPara->nSymbStart;
461 nSymb = pTaskPara->nSymbNum;
462 iSplit = pTaskPara->nSplitIndex;
463 rte_panic("\nsf %d nSymbStart %d nSymb %d iSplit %d", nSfIdx, nSymbStart, nSymb, iSplit);
465 rte_panic("OFDM_SYMB_SPLIT == pTaskPara->eSplitType");
468 // This is the loop of real OFDM symbol index
469 for(iOfdmSymb = nSymbStart; iOfdmSymb < (nSymbStart + nSymb); iOfdmSymb ++)
470 nSymMask |= (1 << iOfdmSymb);
472 app_io_xran_dl_post_func(pEventCtrl->nCellIdx, pEventCtrl->nSlotIdx, /*0x3FFF*/ nSymMask, nLayerStart, nLayer);
476 mlogVar[mlogVarCnt++] = 0xefefefef;
477 mlogVar[mlogVarCnt++] = nCellIdx;
478 mlogVar[mlogVarCnt++] = nSfIdx;
479 mlogVar[mlogVarCnt++] = nSymbStart;
480 mlogVar[mlogVarCnt++] = nSymb;
481 mlogVar[mlogVarCnt++] = nLayerStart;
482 mlogVar[mlogVarCnt++] = nLayer;
483 mlogVar[mlogVarCnt++] = iSplit;
484 MLogAddVariables(mlogVarCnt, mlogVar, mlog_start);
488 //unlock the next task
489 next_event_unlock(pCookies);
491 MLogTask(PCID_GNB_DL_POST_CC0+nCellIdx, mlog_start, MLogTick());
492 return EBBUPOOL_CORRECT;