* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / app / src / app_dl_bbu_pool_tasks.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2020 Intel.
4 *
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
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 *******************************************************************************/
18
19 /**
20  * @brief This module provides implementation of BBU tasks for sample app
21  * @file app_bbu.c
22  * @ingroup xran
23  * @author Intel Corporation
24  *
25  **/
26
27 #include <unistd.h>
28 #include <memory.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <pthread.h>
33 #include <immintrin.h>
34
35 #include "common.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"
42
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];
46
47 void app_bbu_pool_pre_task_dl_post(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara)
48 {
49     int32_t nSplitGroup = 0;
50     int32_t iTask = 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;
62
63     if(psXranIoIf == NULL)
64         rte_panic("psXranIoIf == NULL");
65
66     if(nCellIdx >= MAX_PHY_INSTANCES)
67         rte_panic("nCellIdx >= MAX_PHY_INSTANCES");
68
69     xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
70
71     if(xran_port < 0) {
72         printf("incorrect xran_port\n");
73         return /*EBBUPOOL_CORRECT*/;
74     }
75
76     // psIoCtrl = app_io_xran_if_ctrl_get(xran_port);
77     pXranConf = &app_io_xran_fh_config[xran_port];
78     if(pXranConf == NULL)
79         rte_panic("pXranConf");
80
81     nTotalLayers = pXranConf->neAxc;
82     nSplitGroup  =  pXranConf->neAxc;
83
84     /* all symp per eAxC */
85     nSymbStart = 0;
86     // nTotalSymb = XRAN_NUM_OF_SYMBOL_PER_SLOT;
87     nSymbPerSplit  = XRAN_NUM_OF_SYMBOL_PER_SLOT;
88
89     nLayerPerSplit = nTotalLayers/nSplitGroup;
90
91     pPara->nTaskNum = nSplitGroup;
92     for (iTask = 0; iTask < (nSplitGroup-1) && iTask < (MAX_TEST_SPLIT_NUM-1); iTask ++)
93     {
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;
106     }
107
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;
118
119     return;
120 }
121
122 void app_bbu_pool_pre_task_dl_cfg(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara)
123 {
124     int32_t nSplitGroup = 0;
125     int32_t iTask = 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;
137     uint32_t neAxc = 0;
138
139     if(psXranIoIf == NULL)
140         rte_panic("psXranIoIf == NULL");
141
142     if(nCellIdx >= MAX_PHY_INSTANCES)
143         rte_panic("nCellIdx >= MAX_PHY_INSTANCES");
144
145     xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
146
147     if(xran_port < 0) {
148         printf("incorrect xran_port\n");
149         return /*EBBUPOOL_CORRECT*/;
150     }
151
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");
156
157     pXranConf = &app_io_xran_fh_config[xran_port];
158     if(pXranConf == NULL)
159         rte_panic("pXranConf");
160
161     if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_A){
162         neAxc = pXranConf->neAxc;
163         nSplitGroup  =  1;
164     } else if (pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B) {
165         neAxc = pXranConf->neAxc;
166         nSplitGroup  =  neAxc;
167     } else
168         rte_panic("neAxc");
169
170     nTotalLayers = neAxc;
171
172     /* all symb per eAxC */
173     nSymbStart = 0;
174     nSymbPerSplit  = XRAN_NUM_OF_SYMBOL_PER_SLOT;
175
176     nLayerPerSplit = nTotalLayers/nSplitGroup;
177
178     pPara->nTaskNum = nSplitGroup;
179     for (iTask = 0; iTask < (nSplitGroup-1) && iTask < (MAX_TEST_SPLIT_NUM-1); iTask ++)
180     {
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;
193     }
194
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;
205
206     return;
207 }
208
209 //-------------------------------------------------------------------------------------------
210 /** @ingroup xran
211 *
212 *  @param[in]   pCookies task input parameter
213 *  @return  0 if SUCCESS
214 *
215 *  @description
216 *  This function takes the DL Config from MAC and stores it into PHY Internal structures.
217 *  and initials the parameter of UL DCI.
218 *
219 **/
220 //-------------------------------------------------------------------------------------------
221 int32_t
222 app_bbu_pool_task_dl_config(void *pCookies)
223 {
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;
238     int32_t flowId;
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;
243
244     if(psXranIoIf == NULL)
245         rte_panic("psXranIoIf == NULL");
246
247     xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
248
249     if(xran_port < 0) {
250         printf("incorrect xran_port\n");
251         return EBBUPOOL_CORRECT;
252     }
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");
257
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;
267
268     p_o_xu_cfg = p_startupConfiguration[xran_port];
269
270
271     mlog_start = MLogTick();
272
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);
278     } else {
279         rte_panic("LAYER_SPLIT == pTaskPara->eSplitType");
280     }
281
282     if(p_o_xu_cfg->p_buff) {
283         p_iq = p_o_xu_cfg->p_buff;
284     } else {
285         rte_panic("Error p_o_xu_cfg->p_buff\n");
286     }
287     tti = nSfIdx;
288     for(cc_id = nRuCcidx; cc_id < psXranIoIf->num_cc_per_port[xran_port]; cc_id++) {
289         if (cc_id >= XRAN_MAX_SECTOR_NR)
290         {
291             rte_panic("cell id %d exceeding max number", cc_id);
292         }
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;
296             } else {
297                 flowId = p_o_xu_cfg->numUlAxc * cc_id + ant_id;
298             }
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");
305                     }
306                 }
307             }
308         }
309     }
310
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);
313
314     if (mlogVariablesCnt)
315         MLogAddVariables((uint32_t)mlogVariablesCnt, (uint32_t *)mlogVariables, mlog_start);
316
317     //unlock the next task
318     next_event_unlock(pCookies);
319     MLogTask(PCID_GNB_DL_CFG_CC0+nCellIdx, mlog_start, MLogTick());
320
321     return EBBUPOOL_CORRECT;
322 }
323
324 int32_t
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)
327 {
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;
336     int32_t flowId = 0;
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;
340
341     xran_port = app_io_xran_map_cellid_to_port(psXranIoIf, nCellIdx, &nRuCcidx);
342
343     if(xran_port < 0)
344     {
345         printf("incorrect xran_port\n");
346         return FAILURE;
347     }
348
349     psIoCtrl = app_io_xran_if_ctrl_get(xran_port);
350
351     if(psIoCtrl == NULL) {
352         printf("psIoCtrl == NULL\n");
353         return FAILURE;
354     }
355
356     p_o_xu_cfg = p_startupConfiguration[xran_port];
357     if(p_o_xu_cfg == NULL) {
358         printf("p_o_xu_cfg == NULL\n");
359         return FAILURE;
360     }
361
362     if(p_o_xu_cfg->p_buff) {
363         p_iq = p_o_xu_cfg->p_buff;
364     } else {
365         rte_panic("Error p_o_xu_cfg->p_buff\n");
366     }
367
368     pXranConf = &app_io_xran_fh_config[xran_port];
369
370     tti = nSlotIdx;
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;
375             } else {
376                 flowId = p_o_xu_cfg->numUlAxc * cc_id + ant_id;
377             }
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");
384                     }
385                 }
386             }
387         }
388     }
389
390     xran_prepare_up_dl_sym(xran_port, nSlotIdx, nRuCcidx, 1, nSymMask, nAntStart, nAntNum, nSymStart, nSymNum);
391     return SUCCESS;
392 }
393
394 int32_t
395 app_io_xran_dl_post_func(uint16_t nCellIdx, uint32_t nSfIdx, uint32_t nSymMask,  uint32_t nAntStart, uint32_t nAntNum)
396 {
397     uint16_t phyInstance = nCellIdx;
398     // uint32_t Ntx_antennas;
399     uint16_t nOranCellIdx;
400
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;
407
408     nSymMask = nSymMask + 0;
409
410     nOranCellIdx = nCellIdx;
411     xran_port =  app_io_xran_map_cellid_to_port(psXranIoIf, nOranCellIdx, &nRuCcidx);
412     if(xran_port < 0) {
413         printf("incorrect xran_port\n");
414         return FAILURE;
415     }
416
417     // pXranConf = &app_io_xran_fh_config[xran_port];
418 //    Ntx_antennas = pXranConf->neAxc;
419
420     app_io_xran_dl_pack_func(nCellIdx, nSfIdx, nSymMask, nAntStart, nAntNum, 0, XRAN_NUM_OF_SYMBOL_PER_SLOT);
421
422     MLogTask(PCID_GNB_DL_IQ_COMPRESS_CC0 + phyInstance, tTotal, MLogTick());
423
424     return SUCCESS;
425 }
426
427 //-------------------------------------------------------------------------------------------
428 /** @ingroup group_nr5g_source_phy_pdsch
429 *
430 *  @param[in]   pCookies task input parameter
431 *  @return  0 if SUCCESS
432 *
433 *  @description
434 *  This function will reset phy dl buffers.
435 *
436 **/
437 //-------------------------------------------------------------------------------------------
438 int32_t app_bbu_pool_task_dl_post(void *pCookies)
439 {
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;
446     uint64_t mlog_start;
447     uint32_t mlogVar[10];
448     uint32_t mlogVarCnt = 0;
449     uint16_t nLayerStart = 0, nLayer = 0;
450     mlog_start = MLogTick();
451
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);
464     } else {
465         rte_panic("OFDM_SYMB_SPLIT == pTaskPara->eSplitType");
466     }
467
468     // This is the loop of real OFDM symbol index
469     for(iOfdmSymb = nSymbStart; iOfdmSymb < (nSymbStart + nSymb); iOfdmSymb ++)
470         nSymMask |= (1 << iOfdmSymb);
471
472     app_io_xran_dl_post_func(pEventCtrl->nCellIdx, pEventCtrl->nSlotIdx, /*0x3FFF*/ nSymMask, nLayerStart, nLayer);
473
474 #if 1
475     {
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);
485     }
486 #endif
487
488     //unlock the next task
489     next_event_unlock(pCookies);
490
491     MLogTask(PCID_GNB_DL_POST_CC0+nCellIdx, mlog_start, MLogTick());
492     return EBBUPOOL_CORRECT;
493 }
494