4ccc6f23ae413d70bbf92ef4b4d6384d25935c56
[o-du/phy.git] / fhi_lib / test / common / xran_lib_wrap.hpp
1 /******************************************************************************
2 *
3 *   Copyright (c) 2019 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 #ifndef XRAN_LIB_WRAP_HPP
21 #define XRAN_LIB_WRAP_HPP
22
23 #include <exception>
24 #include <random>
25 #include <string>
26 #include <utility>
27 #include <vector>
28
29 #include <malloc.h>
30 #include <stdint.h>
31
32 #include "common.hpp"
33 #include "xran_fh_o_du.h"
34 #include "xran_common.h"
35 #include "xran_frame_struct.h"
36
37
38 #define XRAN_UT_CFG_FILENAME            "conf.json"
39
40 #define XRAN_UT_KEY_GLOBALCFG           "GLOBAL"
41 #define XRAN_UT_KEY_GLOBALCFG_IO        "io_cfg"
42 #define XRAN_UT_KEY_GLOBALCFG_EAXCID    "eAxCId_cfg"
43 #define XRAN_UT_KEY_GLOBALCFG_PRACH     "prach_cfg"
44 #define XRAN_UT_KEY_GLOBALCFG_RU        "ru_cfg"
45 #define XRAN_UT_KEY_GLOBALCFG_SLOT      "slotcfg_"
46
47 #define MAX_NUM_OF_XRAN_CTX             (2)
48
49 #define SW_FPGA_TOTAL_BUFFER_LEN        (4*1024*1024*1024)
50 #define SW_FPGA_SEGMENT_BUFFER_LEN      (1*1024*1024*1024)
51 #define SW_FPGA_FH_TOTAL_BUFFER_LEN     (1*1024*1024*1024)
52 #define FPGA_TO_SW_PRACH_RX_BUFFER_LEN  (8192)
53
54 #define MAX_ANT_CARRIER_SUPPORTED (XRAN_MAX_SECTOR_NR*XRAN_MAX_ANTENNA_NR)
55
56 extern "C"
57 {
58 extern uint32_t xran_lib_ota_tti;
59 extern uint32_t xran_lib_ota_sym;
60 extern uint32_t xran_lib_ota_sym_idx;
61
62 void sym_ota_cb(struct rte_timer *tim, void *arg);
63 void tti_ota_cb(struct rte_timer *tim, void *arg);
64 }
65
66 class xranLibWraper
67 {
68 public:
69     typedef enum
70     {
71         XRANFTHTX_OUT = 0,
72         XRANFTHTX_PRB_MAP_OUT,
73         XRANFTHTX_SEC_DESC_OUT,
74         XRANFTHRX_IN,
75         XRANFTHRX_PRB_MAP_IN,
76         XRANFTHTX_SEC_DESC_IN,
77         XRANFTHRACH_IN,
78         MAX_SW_XRAN_INTERFACE_NUM
79     } SWXRANInterfaceTypeEnum;
80
81     enum nChBw
82     {
83         PHY_BW_5MHZ   =   5, PHY_BW_10MHZ  =  10, PHY_BW_15MHZ  =  15,
84         PHY_BW_20MHZ  =  20, PHY_BW_25MHZ  =  25, PHY_BW_30MHZ  =  30,
85         PHY_BW_40MHZ  =  40, PHY_BW_50MHZ  =  50, PHY_BW_60MHZ  =  60,
86         PHY_BW_70MHZ  =  70, PHY_BW_80MHZ  =  80, PHY_BW_90MHZ  =  90,
87         PHY_BW_100MHZ = 100, PHY_BW_200MHZ = 200, PHY_BW_400MHZ = 400
88     };
89
90     // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
91     const uint16_t nNumRbsPerSymF1[3][13] =
92     {
93     //      5MHz   10MHz   15MHz   20MHz   25MHz   30MHz   40MHz   50MHz   60MHz   70MHz   80MHz   90MHz  100MHz
94         {    25,     52,     79,    106,    133,    160,    216,    270,      0,      0,      0,      0,      0 },  // Numerology 0 (15KHz)
95         {    11,     24,     38,     51,     65,     78,    106,    133,    162,      0,    217,    245,    273 },  // Numerology 1 (30KHz)
96         {     0,     11,     18,     24,     31,     38,     51,     65,     79,      0,    107,    121,    135 }   // Numerology 2 (60KHz)
97     };
98
99     // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
100     const uint16_t nNumRbsPerSymF2[2][4] =
101     {
102     //     50MHz  100MHz  200MHz  400MHz
103         {    66,    132,    264,      0 },  // Numerology 2 (60KHz)
104         {    32,     66,    132,    264 }   // Numerology 3 (120KHz)
105     };
106
107
108 protected:
109     char argv[25] = "unittest";
110
111     std::string m_dpdk_dev_up, m_dpdk_dev_cp, m_dpdk_bbdev;
112
113     void *m_xranhandle;
114
115     uint8_t m_du_mac[6] = { 0x00,0x11, 0x22, 0x33, 0x44, 0x66 };
116     uint8_t m_ru_mac[6] = { 0x00,0x11, 0x22, 0x33, 0x44, 0x55 };
117     bool m_bSub6;
118     uint32_t m_nSlots = 10;
119
120     struct xran_fh_config   m_xranConf;
121     struct xran_fh_init     m_xranInit;
122
123     struct xran_timer_ctx {
124         uint32_t    tti_to_process;
125         } m_timer_ctx[MAX_NUM_OF_XRAN_CTX];
126
127     /* io struct */
128     BbuIoBufCtrlStruct m_sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
129     BbuIoBufCtrlStruct m_sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
130     BbuIoBufCtrlStruct m_sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
131     BbuIoBufCtrlStruct m_sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
132     BbuIoBufCtrlStruct m_sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
133
134     /* buffers lists */
135     struct xran_flat_buffer m_sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
136     struct xran_flat_buffer m_sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
137     struct xran_flat_buffer m_sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
138     struct xran_flat_buffer m_sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
139     struct xran_flat_buffer m_sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
140
141     void    *m_nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
142     uint32_t m_nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM];   // every api owns unique buffer pool
143
144     uint32_t m_nSW_ToFpga_FTH_TxBufferLen;
145     uint32_t m_nFpgaToSW_FTH_RxBufferLen;
146
147     int32_t m_nSectorIndex[XRAN_MAX_SECTOR_NR];
148
149     int iq_bfw_buffer_size_dl = 0;
150     int iq_bfw_buffer_size_ul = 0;
151
152     /* beamforming weights for UL (O-DU) */
153     int16_t *p_tx_dl_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
154     int32_t tx_dl_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
155     int32_t tx_dl_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
156
157     /* beamforming weights for UL (O-DU) */
158     int16_t *p_tx_ul_bfw_buffer[MAX_ANT_CARRIER_SUPPORTED];
159     int32_t tx_ul_bfw_buffer_size[MAX_ANT_CARRIER_SUPPORTED];
160     int32_t tx_ul_bfw_buffer_position[MAX_ANT_CARRIER_SUPPORTED];
161
162
163 private:
164     json m_global_cfg;
165
166     template<typename T>
167     T get_globalcfg(const std::string &type, const std::string &parameter_name)
168     {
169         return m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name];
170     }
171
172     template<typename T>
173     std::vector<T> get_globalcfg_array(const std::string &type, const std::string &parameter_name)
174     {
175         auto array_size = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name].size();
176
177         std::vector<T> result(array_size);
178
179         for(unsigned number = 0; number < array_size; number++)
180             result.at(number) = m_global_cfg[XRAN_UT_KEY_GLOBALCFG][type][parameter_name][number];
181
182         return result;
183     }
184
185     uint16_t get_eaxcid_mask(int numbit, int shift)
186     {
187         uint16_t result = 0;
188
189         for(int i=0; i < numbit; i++) {
190             result = result << 1; result +=1;
191             }
192         return (result << shift);
193     }
194
195     int init_memory()
196     {
197         xran_status_t status;
198         int32_t i, j, k, z;
199         SWXRANInterfaceTypeEnum eInterfaceType;
200         void *ptr;
201         void *mb;
202         uint32_t *u32dptr;
203         uint16_t *u16dptr;
204         uint8_t  *u8dptr;
205
206
207         std::cout << "XRAN front haul xran_mm_init" << std::endl;
208         status = xran_mm_init(m_xranhandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
209         if(status != XRAN_STATUS_SUCCESS) {
210             std::cout << "Failed at XRAN front haul xran_mm_init" << std::endl;
211             return (-1);
212             }
213
214         /* initialize maximum instances to have flexibility for the tests */
215         int nInstanceNum = XRAN_MAX_SECTOR_NR;
216         /* initialize maximum supported CC to have flexibility on the test */
217         int32_t nSectorNum = 6;//XRAN_MAX_SECTOR_NR;
218
219         for(k = 0; k < XRAN_PORTS_NUM; k++) {
220             status = xran_sector_get_instances(m_xranhandle, nInstanceNum, &m_nInstanceHandle[k][0]);
221             if(status != XRAN_STATUS_SUCCESS) {
222                 std::cout  << "get sector instance failed " << k << " for XRAN nInstanceNum " << nInstanceNum << std::endl;
223                 return (-1);
224                 }
225             for (i = 0; i < nInstanceNum; i++)
226                 std::cout << __func__ << " [" << k << "]: CC " << i << " handle " << m_nInstanceHandle[0][i] << std::endl;
227             }
228         std::cout << "Sucess xran_mm_init" << std::endl;
229
230         /* Init Memory */
231         for(i = 0; i<nSectorNum; i++) {
232             eInterfaceType = XRANFTHTX_OUT;
233             status = xran_bm_init(m_nInstanceHandle[0][i],
234                             &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
235                             XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT,
236                             m_nSW_ToFpga_FTH_TxBufferLen);
237             if(status != XRAN_STATUS_SUCCESS) {
238                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
239                 return (-1);
240                 }
241             for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
242                 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
243                     m_sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
244                     m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
245                     m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
246                     m_sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
247                     m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
248                     m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulTxBuffers[j][i][z][0];
249
250                     for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
251                         m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = m_nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
252                         m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
253                         m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
254                         status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
255                         if(status != XRAN_STATUS_SUCCESS) {
256                             std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer, status " << status << std::endl;
257                             return (-1);
258                             }
259                         m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
260                         m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
261
262                         if(ptr) {
263                             u32dptr = (uint32_t*)(ptr);
264                             uint8_t *ptr_temp = (uint8_t *)ptr;
265                             memset(u32dptr, 0x0, m_nSW_ToFpga_FTH_TxBufferLen);
266                             }
267                         }
268                     }
269                 }
270
271             /* C-plane DL */
272             eInterfaceType = XRANFTHTX_SEC_DESC_OUT;
273             status = xran_bm_init(m_nInstanceHandle[0][i],
274                             &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
275                             XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc));
276             if(XRAN_STATUS_SUCCESS != status) {
277                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
278                 return (-1);
279             }
280             eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
281             status = xran_bm_init(m_nInstanceHandle[0][i],
282                             &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
283                             XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT,
284                             sizeof(struct xran_prb_map));
285             if(status != XRAN_STATUS_SUCCESS) {
286                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
287                 return (-1);
288             }
289             for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
290                 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++) {
291                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
292                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
293                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
294                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
295                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
296                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &m_sFrontHaulTxPrbMapBuffers[j][i][z];
297
298                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
299                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
300                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
301                     status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
302                     if(status != XRAN_STATUS_SUCCESS) {
303                         std::cout << __LINE__ << " Failed at xran_bm_allocate_buffer, status " << status << std::endl;
304                         return (-1);
305                         }
306                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
307                     m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
308                     void *sd_ptr;
309                     void *sd_mb;
310                     int  elm_id;
311                     struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
312                     //memcpy(ptr, &startupConfiguration.PrbMap, sizeof(struct xran_prb_map));
313                     for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SYM; elm_id++){
314                         struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
315                         for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
316                             status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_OUT], &sd_ptr, &sd_mb);
317                             if(XRAN_STATUS_SUCCESS != status){
318                                 std::cout << __LINE__ << "SD Failed at  xran_bm_allocate_buffer , status %d\n" << status << std::endl;
319                                 return (-1);
320                             }
321                             pPrbElem->p_sec_desc[k] = (struct xran_section_desc *)sd_ptr;
322                         }
323                     }
324                  }
325              }
326         }
327
328         for(i = 0; i<nSectorNum; i++) {
329             eInterfaceType = XRANFTHRX_IN;
330             status = xran_bm_init(m_nInstanceHandle[0][i],
331                             &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
332                             XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT,
333                             m_nSW_ToFpga_FTH_TxBufferLen);  /* ????, actual alloc size is m_nFpgaToSW_FTH_RxBUfferLen */
334             if(status != XRAN_STATUS_SUCCESS) {
335                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
336                 return (-1);
337                 }
338
339             for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
340                 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++) {
341                     m_sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid                  = 0;
342                     m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated           = -1;
343                     m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen             = -1;
344                     m_sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred         = 0;
345                     m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
346                     m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers    = &m_sFrontHaulRxBuffers[j][i][z][0];
347                     for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
348                         m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes  = m_nFpgaToSW_FTH_RxBufferLen;
349                         m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements   = 1;
350                         m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes      = 0;
351                         status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],&ptr, &mb);
352                         if(status != XRAN_STATUS_SUCCESS) {
353                             std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer, status " << status << std::endl;
354                             return (-1);
355                             }
356                         m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData   = (uint8_t *)ptr;
357                         m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl   = (void *) mb;
358                         if(ptr) {
359                             u32dptr = (uint32_t*)(ptr);
360                             uint8_t *ptr_temp = (uint8_t *)ptr;
361                             memset(u32dptr, 0x0, m_nFpgaToSW_FTH_RxBufferLen);
362                             }
363                         }
364                     }
365                 }
366
367             eInterfaceType = XRANFTHTX_SEC_DESC_IN;
368             status = xran_bm_init(m_nInstanceHandle[0][i],
369                             &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
370                             XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc));
371             if(XRAN_STATUS_SUCCESS != status) {
372                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
373                 return (-1);
374             }
375             eInterfaceType = XRANFTHRX_PRB_MAP_IN;
376             status = xran_bm_init(m_nInstanceHandle[0][i],
377                                 &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
378                                 XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT,
379                                 sizeof(struct xran_prb_map));
380             if(status != XRAN_STATUS_SUCCESS) {
381                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
382                 return (-1);
383             }
384
385             for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
386                 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++) {
387                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid                    = 0;
388                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated             = -1;
389                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen               = -1;
390                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred           = 0;
391                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers   = XRAN_NUM_OF_SYMBOL_PER_SLOT;
392                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers      = &m_sFrontHaulRxPrbMapBuffers[j][i][z];
393
394                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes  = sizeof(struct xran_prb_map);
395                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements   = 1;
396                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes      = 0;
397                     status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i],m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
398                     if(status != XRAN_STATUS_SUCCESS) {
399                         std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer , status " << status << std::endl;
400                         return (-1);
401                         }
402                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData   = (uint8_t *)ptr;
403                     m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl   = (void *)mb;
404                     void *sd_ptr;
405                     void *sd_mb;
406                     int  elm_id;
407                     struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
408                     //memcpy(ptr, &startupConfiguration.PrbMap, sizeof(struct xran_prb_map));
409                     for (elm_id = 0; elm_id < XRAN_MAX_SECTIONS_PER_SYM; elm_id++){
410                         struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
411                         for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
412                             status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][XRANFTHTX_SEC_DESC_IN], &sd_ptr, &sd_mb);
413                             if(XRAN_STATUS_SUCCESS != status){
414                                 std::cout << __LINE__ << "SD Failed at  xran_bm_allocate_buffer , status %d\n" << status << std::endl;
415                                 return (-1);
416                             }
417                             pPrbElem->p_sec_desc[k] = (struct xran_section_desc *)sd_ptr;
418                         }
419                     }
420                 }
421             }
422         }
423
424         for(i = 0; i<nSectorNum; i++) {
425             eInterfaceType = XRANFTHRACH_IN;
426             status = xran_bm_init(m_nInstanceHandle[0][i],
427                                 &m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType],
428                                 XRAN_N_FE_BUF_LEN * XRAN_MAX_ANTENNA_NR * XRAN_NUM_OF_SYMBOL_PER_SLOT,
429                                 FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
430             if(status != XRAN_STATUS_SUCCESS) {
431                 std::cout << __LINE__ << " Failed at xran_bm_init, status " << status << std::endl;
432                 return (-1);
433                 }
434             for(j = 0; j < XRAN_N_FE_BUF_LEN; j++) {
435                 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++) {
436                     m_sFHPrachRxBbuIoBufCtrl[j][i][z].bValid                    = 0;
437                     m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated             = -1;
438                     m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen               = -1;
439                     m_sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred           = 0;
440                     m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers   = XRAN_MAX_ANTENNA_NR;
441                     m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers      = &m_sFHPrachRxBuffers[j][i][z][0];
442                     for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++) {
443                         m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes    = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
444                         m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements     = 1;
445                         m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes        = 0;
446                         status = xran_bm_allocate_buffer(m_nInstanceHandle[0][i], m_nBufPoolIndex[m_nSectorIndex[i]][eInterfaceType], &ptr, &mb);
447                         if(status != XRAN_STATUS_SUCCESS) {
448                             std::cout << __LINE__ << " Failed at  xran_bm_allocate_buffer, status " << status << std::endl;
449                             return (-1);
450                             }
451                         m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
452                         m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
453                         if(ptr) {
454                             u32dptr = (uint32_t*)(ptr);
455                             memset(u32dptr, 0x0, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
456                             }
457                         }
458                     }
459                 }
460             }
461
462         return (0);
463     }
464
465
466 public:
467     xranLibWraper()
468     {
469         int i, temp;
470         std::string tmpstr;
471         unsigned int tmp_mac[6];
472
473         m_global_cfg = read_json_from_file(XRAN_UT_CFG_FILENAME);
474
475         memset(&m_xranInit, 0, sizeof(xran_fh_init));
476
477         m_xranInit.io_cfg.id  = 0;
478
479         /* DPDK configuration */
480         m_dpdk_dev_up = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_up");
481         m_dpdk_dev_cp = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdk_dev_cp");
482         m_xranInit.io_cfg.dpdk_dev[XRAN_UP_VF]  = (m_dpdk_dev_up == "") ? NULL : (char *)&m_dpdk_dev_up;
483         m_xranInit.io_cfg.dpdk_dev[XRAN_CP_VF]  = (m_dpdk_dev_cp == "") ? NULL : (char *)&m_dpdk_dev_cp;
484
485         m_xranInit.io_cfg.core              = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "core");
486         m_xranInit.io_cfg.system_core       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "system_core");
487         m_xranInit.io_cfg.pkt_proc_core     = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_proc_core");
488         m_xranInit.io_cfg.pkt_aux_core      = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "pkt_aux_core");
489         m_xranInit.io_cfg.timing_core       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "timing_core");
490
491         std::string bbdev_mode = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "bbdev_mode");
492         if(bbdev_mode == "sw")
493             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_MODE_HW_OFF;
494         else if(bbdev_mode == "hw")
495             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_MODE_HW_ON;
496         else if(bbdev_mode == "none")
497             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_NOT_USED;
498         else {
499             std::cout << "Invalid BBDev mode [" << bbdev_mode << "], bbdev won't be used." << std::endl;
500             m_xranInit.io_cfg.bbdev_mode    = XRAN_BBDEV_NOT_USED;
501             }
502
503         m_xranInit.dpdkBasebandFecMode      = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandFecMode");
504
505         m_dpdk_bbdev = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "dpdkBasebandDevice");
506         m_xranInit.dpdkBasebandDevice       = (m_dpdk_bbdev == "") ? NULL : (char *)&m_dpdk_bbdev;
507
508         /* Network configurations */
509         m_xranInit.mtu          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "mtu");
510
511         std::string du_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_du_macaddr");
512         std::string ru_mac_str = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_IO, "o_ru_macaddr");
513         /* using temp variables to resolve KW issue */
514         std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
515                                            &tmp_mac[0], &tmp_mac[1], &tmp_mac[2],
516                                            &tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
517         for(i=0; i<6; i++)
518             m_du_mac[i] = (uint8_t)tmp_mac[i];
519         std::sscanf(du_mac_str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x",
520                                            &tmp_mac[0], &tmp_mac[1], &tmp_mac[2],
521                                            &tmp_mac[3], &tmp_mac[4], &tmp_mac[5]);
522         for(i=0; i<6; i++)
523             m_ru_mac[i] = (uint8_t)tmp_mac[i];
524         m_xranInit.p_o_du_addr  = (int8_t *)m_du_mac;
525         m_xranInit.p_o_ru_addr  = (int8_t *)m_ru_mac;
526         m_xranInit.cp_vlan_tag  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "cp_vlan_tag");
527         m_xranInit.up_vlan_tag  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_IO, "up_vlan_tag");
528
529         /* eAxCID configurations */
530         int bitnum_cuport   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_cuPortId");
531         int bitnum_bandsec  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_bandSectorId");
532         int bitnum_ccid     = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ccId");
533         int bitnum_ruport   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_EAXCID, "bit_ruPortId");
534
535         m_xranInit.eAxCId_conf.bit_cuPortId       = bitnum_bandsec + bitnum_ccid + bitnum_ruport;
536         m_xranInit.eAxCId_conf.bit_bandSectorId   = bitnum_ccid + bitnum_ruport;
537         m_xranInit.eAxCId_conf.bit_ccId           = bitnum_ruport;
538         m_xranInit.eAxCId_conf.bit_ruPortId       = 0;
539         m_xranInit.eAxCId_conf.mask_cuPortId      = get_eaxcid_mask(bitnum_cuport, m_xranInit.eAxCId_conf.bit_cuPortId);
540         m_xranInit.eAxCId_conf.mask_bandSectorId  = get_eaxcid_mask(bitnum_bandsec, m_xranInit.eAxCId_conf.bit_bandSectorId);
541         m_xranInit.eAxCId_conf.mask_ccId          = get_eaxcid_mask(bitnum_ccid, m_xranInit.eAxCId_conf.bit_ccId);
542         m_xranInit.eAxCId_conf.mask_ruPortId      = get_eaxcid_mask(bitnum_ruport, m_xranInit.eAxCId_conf.bit_ruPortId);
543
544         m_xranInit.totalBfWeights   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "totalBfWeights");
545
546         m_xranInit.Tadv_cp_dl       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Tadv_cp_dl");
547         m_xranInit.T2a_min_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_dl");
548         m_xranInit.T2a_max_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_dl");
549         m_xranInit.T2a_min_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_cp_ul");
550         m_xranInit.T2a_max_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_cp_ul");
551         m_xranInit.T2a_min_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_min_up");
552         m_xranInit.T2a_max_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T2a_max_up");
553         m_xranInit.Ta3_min          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_min");
554         m_xranInit.Ta3_max          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta3_max");
555         m_xranInit.T1a_min_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_dl");
556         m_xranInit.T1a_max_cp_dl    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_dl");
557         m_xranInit.T1a_min_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_cp_ul");
558         m_xranInit.T1a_max_cp_ul    = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_cp_ul");
559         m_xranInit.T1a_min_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_min_up");
560         m_xranInit.T1a_max_up       = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "T1a_max_up");
561         m_xranInit.Ta4_min          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_min");
562         m_xranInit.Ta4_max          = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "Ta4_max");
563
564         m_xranInit.enableCP         = 1;
565         m_xranInit.prachEnable      = 1;
566         m_xranInit.debugStop        = 0;
567         m_xranInit.debugStopCount   = 0;
568         m_xranInit.DynamicSectionEna= 0;
569
570         m_xranInit.filePrefix   = "wls";
571
572         m_bSub6     = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
573
574         memset(&m_xranConf, 0, sizeof(struct xran_fh_config));
575         tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "duplex");
576         if(tmpstr == "FDD") {
577             m_xranConf.frame_conf.nFrameDuplexType  = 0;
578             }
579         else if(tmpstr == "TDD") {
580             m_xranConf.frame_conf.nFrameDuplexType  = 1;
581
582             std::string slotcfg_key = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "slot_config");
583
584             int numcfg = get_globalcfg<int>(slotcfg_key, "period");
585             m_xranConf.frame_conf.nTddPeriod = numcfg;
586
587             for(int i=0; i< numcfg; i++) {
588                 std::stringstream slotcfgname;
589                 slotcfgname << "slot" << i;
590                 std::vector<int> slotcfg = get_globalcfg_array<int>(slotcfg_key, slotcfgname.str());
591                 for(int j=0; j < slotcfg.size(); j++) {
592                     m_xranConf.frame_conf.sSlotConfig[i].nSymbolType[j] = slotcfg[j];
593                     }
594                 m_xranConf.frame_conf.sSlotConfig[i].reserved[0] = 0;
595                 m_xranConf.frame_conf.sSlotConfig[i].reserved[1] = 0;
596                 }
597             }
598         else {
599             std::cout << "*** Invalid Duplex type [" << tmpstr << "] !!!" << std::endl;
600             std::cout << "****** Set it to FDD... " << std::endl;
601             m_xranConf.frame_conf.nFrameDuplexType  = 0;
602             }
603
604         m_xranConf.frame_conf.nNumerology = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "mu");
605         if(m_xranConf.frame_conf.nNumerology > 3) {
606             std::cout << "*** Invalid Numerology [" << m_xranConf.frame_conf.nNumerology << "] !!!" << std::endl;
607             m_xranConf.frame_conf.nNumerology   = 0;
608             std::cout << "****** Set it to " << m_xranConf.frame_conf.nNumerology << "..." << std::endl;
609             }
610
611         m_xranConf.nCC = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_cc");
612         if(m_xranConf.nCC > XRAN_MAX_SECTOR_NR) {
613             std::cout << "*** Exceeds maximum number of carriers supported [" << m_xranConf.nCC << "] !!!" << std::endl;
614             m_xranConf.nCC = XRAN_MAX_SECTOR_NR;
615             std::cout << "****** Adjusted to " << m_xranConf.nCC << "..." << std::endl;
616             }
617         m_xranConf.neAxc = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "num_eaxc");
618         if(m_xranConf.neAxc > XRAN_MAX_ANTENNA_NR) {
619             std::cout << "*** Exceeds maximum number of antenna supported [" << m_xranConf.neAxc << "] !!!" << std::endl;
620             m_xranConf.neAxc = XRAN_MAX_ANTENNA_NR;
621             std::cout << "****** Adjusted to " << m_xranConf.neAxc << "..." << std::endl;
622             }
623
624         m_bSub6     = get_globalcfg<bool>(XRAN_UT_KEY_GLOBALCFG_RU, "sub6");
625         temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_dl");
626         m_xranConf.nDLRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
627         temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "chbw_ul");
628         m_xranConf.nULRBs = get_num_rbs(get_numerology(), temp, m_bSub6);
629
630         m_xranConf.nAntElmTRx = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "ant_elm_trx");
631         m_xranConf.nDLFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
632         m_xranConf.nULFftSize = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
633
634         m_xranConf.prach_conf.nPrachConfIdx     = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "config_id");
635         m_xranConf.prach_conf.nPrachSubcSpacing = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "scs");
636         m_xranConf.prach_conf.nPrachFreqStart   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_start");
637         m_xranConf.prach_conf.nPrachFreqOffset  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "freq_offset");
638         m_xranConf.prach_conf.nPrachFilterIdx   = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_PRACH, "filter_id");
639         m_xranConf.prach_conf.nPrachZeroCorrConf= 0;
640         m_xranConf.prach_conf.nPrachRestrictSet = 0;
641         m_xranConf.prach_conf.nPrachRootSeqIdx  = 0;
642
643         tmpstr = get_globalcfg<std::string>(XRAN_UT_KEY_GLOBALCFG_RU, "category");
644         if(tmpstr == "A")
645             m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
646         else if(tmpstr == "B")
647             m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_B;
648         else {
649             std::cout << "*** Invalid RU Category [" << tmpstr << "] !!!" << std::endl;
650             std::cout << "****** Set it to Category A... " << std::endl;
651             m_xranConf.ru_conf.xranCat = XRAN_CATEGORY_A;
652             }
653
654         m_xranConf.ru_conf.iqWidth  = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "iq_width");
655         m_xranConf.ru_conf.compMeth = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "comp_meth");
656
657         temp = get_globalcfg<int>(XRAN_UT_KEY_GLOBALCFG_RU, "fft_size");
658         m_xranConf.ru_conf.fftSize  = 0;
659         while (temp >>= 1)
660             ++m_xranConf.ru_conf.fftSize;
661
662         m_xranConf.ru_conf.byteOrder    =  XRAN_NE_BE_BYTE_ORDER;
663         m_xranConf.ru_conf.iqOrder      =  XRAN_I_Q_ORDER;
664
665         m_xranConf.log_level    = 0;
666 /*
667         m_xranConf.bbdev_enc = nullptr;
668         m_xranConf.bbdev_dec = nullptr;
669         m_xranConf.ttiCb    = nullptr;
670         m_xranConf.ttiCbParam   = nullptr;
671 */
672     }
673
674     ~xranLibWraper()
675     {
676     }
677
678     int SetUp()
679     {
680         int i;
681
682         printf("O-DU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
683             m_xranInit.p_o_du_addr[0],
684             m_xranInit.p_o_du_addr[1],
685             m_xranInit.p_o_du_addr[2],
686             m_xranInit.p_o_du_addr[3],
687             m_xranInit.p_o_du_addr[4],
688             m_xranInit.p_o_du_addr[5]);
689
690         printf("O-RU MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
691             m_xranInit.p_o_ru_addr[0],
692             m_xranInit.p_o_ru_addr[1],
693             m_xranInit.p_o_ru_addr[2],
694             m_xranInit.p_o_ru_addr[3],
695             m_xranInit.p_o_ru_addr[4],
696             m_xranInit.p_o_ru_addr[5]);
697
698         printf("eAxCID - %d:%d:%d:%d (%04x, %04x, %04x, %04x)\n",
699             m_xranInit.eAxCId_conf.bit_cuPortId,
700             m_xranInit.eAxCId_conf.bit_bandSectorId,
701             m_xranInit.eAxCId_conf.bit_ccId,
702             m_xranInit.eAxCId_conf.bit_ruPortId,
703             m_xranInit.eAxCId_conf.mask_cuPortId,
704             m_xranInit.eAxCId_conf.mask_bandSectorId,
705             m_xranInit.eAxCId_conf.mask_ccId,
706             m_xranInit.eAxCId_conf.mask_ruPortId);
707
708         printf("Total BF Weights : %d\n", m_xranInit.totalBfWeights);
709
710         xran_init(0, NULL, &m_xranInit, &argv[0], &m_xranhandle);
711
712         for(i = 0; i < XRAN_MAX_SECTOR_NR; i++)
713             m_nSectorIndex[i] = i;
714
715         /* set to maximum length to support multiple cases */
716         m_nFpgaToSW_FTH_RxBufferLen     = 13168; /* 273*12*4 + 64*/
717         m_nSW_ToFpga_FTH_TxBufferLen    = 13168; /* 273*12*4 + 64*/
718
719         if(init_memory() < 0) {
720             std::cout << "Fatal Error on Initialization !!!" << std::endl;
721             std::cout << "INIT FAILED" << std::endl;
722             return (-1);
723             }
724
725         std::cout << "INIT DONE" << std::endl;
726         return (0);
727     }
728
729     void TearDown()
730     {
731         if(m_xranhandle) {
732             xran_close(m_xranhandle);
733             m_xranhandle = nullptr;
734             std::cout << "CLOSE DONE" << std::endl;
735             }
736         else
737             std::cout << "ALREADY CLOSED" << std::endl;
738     }
739
740     int Init(struct xran_fh_config *pCfg = nullptr)
741     {
742         xran_status_t status;
743         int32_t nSectorNum;
744         int32_t i, j, k, z;
745         void *ptr;
746         void *mb;
747         uint32_t *u32dptr;
748         uint16_t *u16dptr;
749         uint8_t  *u8dptr;
750         SWXRANInterfaceTypeEnum eInterfaceType;
751         int32_t cc_id, ant_id, sym_id, tti;
752         int32_t flowId;
753         char    *pos        = NULL;
754         struct xran_prb_map *pRbMap = NULL;
755
756
757         /* Update member variables */
758         if(pCfg)
759             memcpy(&m_xranConf, pCfg, sizeof(struct xran_fh_config));
760
761         /* Init timer context */
762         xran_lib_ota_tti        = 0;
763         xran_lib_ota_sym        = 0;
764         xran_lib_ota_sym_idx    = 0;
765         for(i=0; i < MAX_NUM_OF_XRAN_CTX; i++)
766             m_timer_ctx[i].tti_to_process = i;
767
768         nSectorNum = get_num_cc();
769
770         /* Cat B RU support */
771         if(get_rucategory() == XRAN_CATEGORY_B) {
772             /* 10 * [14*32*273*2*2] = 4892160 bytes */
773             iq_bfw_buffer_size_dl = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_dlrbs() * 4L);
774             iq_bfw_buffer_size_ul = (m_nSlots * N_SYM_PER_SLOT * get_num_antelmtrx() * get_num_ulrbs() * 4L);
775
776             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
777                 p_tx_dl_bfw_buffer[i]   = (int16_t*)malloc(iq_bfw_buffer_size_dl);
778                 tx_dl_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_dl;
779                 if(p_tx_dl_bfw_buffer[i] == NULL)
780                     return(-1);
781
782                 memset(p_tx_dl_bfw_buffer[i], 'D', iq_bfw_buffer_size_dl);
783                 tx_dl_bfw_buffer_position[i] = 0;
784
785                 p_tx_ul_bfw_buffer[i]    = (int16_t*)malloc(iq_bfw_buffer_size_ul);
786                 tx_ul_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_ul;
787                 if(p_tx_ul_bfw_buffer[i] == NULL)
788                     return (-1);
789
790                 memset(p_tx_ul_bfw_buffer[i], 'U', iq_bfw_buffer_size_ul);
791                 tx_ul_bfw_buffer_position[i] = 0;
792             }
793         }
794
795         /* Init RB map */
796         for(cc_id = 0; cc_id <nSectorNum; cc_id++) {
797             for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti ++) {
798                 for(ant_id = 0; ant_id < XRAN_MAX_ANTENNA_NR; ant_id++) {
799                     flowId = XRAN_MAX_ANTENNA_NR*cc_id + ant_id;
800
801                     /* C-plane DL */
802                     pRbMap = (struct xran_prb_map *)m_sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
803                     if(pRbMap) {
804                         pRbMap->dir                     = XRAN_DIR_DL;
805                         pRbMap->xran_port               = 0;
806                         pRbMap->band_id                 = 0;
807                         pRbMap->cc_id                   = cc_id;
808                         pRbMap->ru_port_id              = ant_id;
809                         pRbMap->tti_id                  = tti;
810                         pRbMap->start_sym_id            = 0;
811
812                         pRbMap->nPrbElm                 = 1;
813                         pRbMap->prbMap[0].nRBStart      = 0;
814                         pRbMap->prbMap[0].nRBSize       = get_num_dlrbs();
815                         pRbMap->prbMap[0].nStartSymb    = 0;
816                         pRbMap->prbMap[0].numSymb       = 14;
817                         pRbMap->prbMap[0].nBeamIndex    = 0;
818                         pRbMap->prbMap[0].compMethod    = XRAN_COMPMETHOD_NONE;
819
820                         if(get_rucategory() == XRAN_CATEGORY_A) {
821                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_ID_BASED;
822                             pRbMap->prbMap[0].bf_weight_update  = 0;
823                             //pRbMap->prbMap[0].bf_attribute.weight[];
824                             //pRbMap->prbMap[0].bf_precoding.weight[];
825                             }
826                         else if(get_rucategory() == XRAN_CATEGORY_B) {
827                             int idxElm;
828                             int iPrb;
829                             char *dl_bfw_pos = ((char*)p_tx_dl_bfw_buffer[flowId]) + tx_dl_bfw_buffer_position[flowId];
830                             struct xran_prb_elm* p_prbMap = NULL;
831                             int num_antelm;
832
833                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_WEIGHT;
834                             pRbMap->prbMap[0].bf_weight_update  = 1;
835
836                             num_antelm = get_num_antelmtrx();
837 #if 0
838                             /* populate beam weights to C-plane for each elm */
839                             pRbMap->bf_weight.nAntElmTRx = num_antelm;
840                             for(idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++){
841                                 p_prbMap = &pRbMap->prbMap[idxElm];
842                                 for (iPrb = p_prbMap->nRBStart; iPrb < (p_prbMap->nRBStart + p_prbMap->nRBSize); iPrb++) {
843                                     /* copy BF W IQs for 1 PRB of */
844                                     rte_memcpy(&pRbMap->bf_weight.weight[iPrb][0], (dl_bfw_pos + (iPrb * num_antelm)*4), num_antelm*4);
845                                     }
846                                 }
847 #endif
848                             } /* else if(get_rucategory() == XRAN_CATEGORY_B) */
849                         } /* if(pRbMap) */
850                     else {
851                         std::cout << "DL pRbMap ==NULL" << std::endl;
852                         }
853
854                     /* C-plane UL */
855                     pRbMap = (struct xran_prb_map *)m_sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
856                     if(pRbMap) {
857                         pRbMap->dir                     = XRAN_DIR_UL;
858                         pRbMap->xran_port               = 0;
859                         pRbMap->band_id                 = 0;
860                         pRbMap->cc_id                   = cc_id;
861                         pRbMap->ru_port_id              = ant_id;
862                         pRbMap->tti_id                  = tti;
863                         pRbMap->start_sym_id            = 0;
864
865                         pRbMap->nPrbElm                 = 1;
866                         pRbMap->prbMap[0].nRBStart      = 0;
867                         pRbMap->prbMap[0].nRBSize       = get_num_ulrbs();
868                         pRbMap->prbMap[0].nStartSymb    = 0;
869                         pRbMap->prbMap[0].numSymb       = 14;
870                         pRbMap->prbMap[0].nBeamIndex    = 0;
871                         pRbMap->prbMap[0].compMethod    = XRAN_COMPMETHOD_NONE;
872
873                         if(get_rucategory() == XRAN_CATEGORY_A) {
874                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_ID_BASED;
875                             pRbMap->prbMap[0].bf_weight_update  = 0;
876                             //pRbMap->prbMap[0].bf_attribute.weight[];
877                             //pRbMap->prbMap[0].bf_precoding.weight[];
878                             }
879                         else if(get_rucategory() == XRAN_CATEGORY_B) {
880                             int idxElm;
881                             int iPrb;
882                             char *ul_bfw_pos =  ((char*)p_tx_ul_bfw_buffer[flowId]) + tx_ul_bfw_buffer_position[flowId];
883                             struct xran_prb_elm* p_prbMap = NULL;
884                             int num_antelm;
885
886                             pRbMap->prbMap[0].BeamFormingType   = XRAN_BEAM_WEIGHT;
887                             pRbMap->prbMap[0].bf_weight_update  = 1;
888
889                             num_antelm = get_num_antelmtrx();
890 #if 0
891                             /* populate beam weights to C-plane for each elm */
892                             pRbMap->bf_weight.nAntElmTRx = num_antelm;
893                             for (idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++){
894                                 p_prbMap = &pRbMap->prbMap[idxElm];
895                                 for (iPrb = p_prbMap->nRBStart; iPrb < (p_prbMap->nRBStart + p_prbMap->nRBSize); iPrb++){
896                                     /* copy BF W IQs for 1 PRB of */
897                                     rte_memcpy(&pRbMap->bf_weight.weight[iPrb][0], (ul_bfw_pos + (iPrb*num_antelm)*4), num_antelm*4);
898                                     }
899                                 }
900 #endif
901                             } /* else if(get_rucategory() == XRAN_CATEGORY_B) */
902
903                         } /* if(pRbMap) */
904                     else {
905                         std::cout << "UL: pRbMap ==NULL" << std::endl;
906                         }
907                     }
908                 }
909             }
910
911         return (0);
912     }
913
914     void Cleanup()
915     {
916         int i;
917
918         if(get_rucategory() == XRAN_CATEGORY_B) {
919             for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(get_num_cc() * get_num_eaxc()); i++) {
920                 if(p_tx_dl_bfw_buffer[i]) {
921                     free(p_tx_dl_bfw_buffer[i]);
922                     p_tx_dl_bfw_buffer[i] == NULL;
923                     }
924
925                 if(p_tx_ul_bfw_buffer[i]) {
926                     free(p_tx_ul_bfw_buffer[i]);
927                     p_tx_ul_bfw_buffer[i] == NULL;
928                     }
929                 }
930             }
931
932         return;
933     }
934
935
936     void Open(xran_ethdi_mbuf_send_fn send_cp, xran_ethdi_mbuf_send_fn send_up,
937             void *fh_rx_callback, void *fh_rx_prach_callback)
938     {
939         struct xran_fh_config *pXranConf;
940         int32_t nSectorNum;
941         int i, j, k, z;
942         struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
943         struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
944         struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
945         struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
946         struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
947
948 #if 0
949         xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
950         xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
951         xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);
952 #endif
953         nSectorNum = get_num_cc();
954
955         for(i=0; i<nSectorNum; i++) {
956             for(j=0; j<XRAN_N_FE_BUF_LEN; j++) {
957                 for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++) {
958                     pFthTxBuffer[i][z][j]       = &(m_sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
959                     pFthTxPrbMapBuffer[i][z][j] = &(m_sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
960                     pFthRxBuffer[i][z][j]       = &(m_sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
961                     pFthRxPrbMapBuffer[i][z][j] = &(m_sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
962                     pFthRxRachBuffer[i][z][j]   = &(m_sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
963                     }
964                 }
965             }
966
967         if(m_nInstanceHandle[0] != NULL) {
968             for(i = 0; i<nSectorNum; i++) {
969                 xran_5g_fronthault_config(m_nInstanceHandle[0][i],
970                         pFthTxBuffer[i], pFthTxPrbMapBuffer[i],
971                         pFthRxBuffer[i], pFthRxPrbMapBuffer[i],
972                         (void (*)(void *, xran_status_t))fh_rx_callback, &pFthRxBuffer[i][0]);
973
974                 xran_5g_prach_req(m_nInstanceHandle[0][i], pFthRxRachBuffer[i],
975                         (void (*)(void *, xran_status_t))fh_rx_prach_callback, &pFthRxRachBuffer[i][0]);
976                 }
977             }
978
979         xran_register_cb_mbuf2ring(send_cp, send_up);
980
981         xran_open(m_xranhandle, &m_xranConf);
982     }
983
984     void Close()
985     {
986         if(m_xranhandle)
987             xran_close(m_xranhandle);
988     }
989
990     int Start()
991     {
992         if(m_xranhandle)
993             return(xran_start(m_xranhandle));
994         else
995             return (-1);
996     }
997
998     int Stop()
999     {
1000         if(m_xranhandle)
1001             return(xran_stop(m_xranhandle));
1002         else
1003             return (-1);
1004     }
1005
1006     /* emulation of timer */
1007     void update_tti()
1008     {
1009         tti_ota_cb(nullptr, get_timer_ctx());
1010     }
1011
1012     void update_symbol_index()
1013     {
1014         xran_lib_ota_sym_idx++;
1015         if((xran_lib_ota_sym_idx % N_SYM_PER_SLOT) == 0) {
1016             update_tti();
1017             }
1018
1019         xran_lib_ota_sym++;
1020         if(xran_lib_ota_sym >= N_SYM_PER_SLOT)
1021             xran_lib_ota_sym = 0;
1022     }
1023
1024     int apply_cpenable(bool flag)
1025     {
1026         struct xran_device_ctx *pCtx = xran_dev_get_ctx();
1027
1028         if(is_running())
1029             return (-1);
1030
1031         if(pCtx == nullptr)
1032             return (-1);
1033
1034         if(flag == true) {
1035             m_xranInit.enableCP = 1;
1036             pCtx->enableCP = 1;
1037             }
1038         else {
1039             m_xranInit.enableCP = 0;
1040             pCtx->enableCP = 0;
1041             }
1042
1043         return (0);
1044     }
1045
1046
1047     int get_slot_config(const std::string &cfgname, struct xran_frame_config *pCfg)
1048     {
1049         int numcfg, i, j;
1050         std::vector<int> slotcfg;
1051
1052         numcfg = get_globalcfg<int>(cfgname, "period");
1053         pCfg->nTddPeriod = numcfg;
1054         for(i=0; i < numcfg; i++) {
1055             std::stringstream slotcfgname;
1056
1057             slotcfgname << "slot" << i;
1058             std::vector<int> slotcfg = get_globalcfg_array<int>(cfgname, slotcfgname.str());
1059
1060             for(j=0; j < slotcfg.size(); j++)
1061                 pCfg->sSlotConfig[i].nSymbolType[j] = slotcfg[j];
1062             pCfg->sSlotConfig[i].reserved[0] = 0; pCfg->sSlotConfig[i].reserved[1] = 0;
1063             }
1064
1065         return (numcfg);
1066     }
1067
1068     int get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, bool nSub6)
1069     {
1070         if(nNumerology > 3)
1071             return (-1);
1072
1073         if(nSub6) {
1074             if (nNumerology < 3) {
1075                 /* F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
1076                 switch(nBandwidth) {
1077                     case PHY_BW_5MHZ:   return(nNumRbsPerSymF1[nNumerology][0]);
1078                     case PHY_BW_10MHZ:  return(nNumRbsPerSymF1[nNumerology][1]);
1079                     case PHY_BW_15MHZ:  return(nNumRbsPerSymF1[nNumerology][2]);
1080                     case PHY_BW_20MHZ:  return(nNumRbsPerSymF1[nNumerology][3]);
1081                     case PHY_BW_25MHZ:  return(nNumRbsPerSymF1[nNumerology][4]);
1082                     case PHY_BW_30MHZ:  return(nNumRbsPerSymF1[nNumerology][5]);
1083                     case PHY_BW_40MHZ:  return(nNumRbsPerSymF1[nNumerology][6]);
1084                     case PHY_BW_50MHZ:  return(nNumRbsPerSymF1[nNumerology][7]);
1085                     case PHY_BW_60MHZ:  return(nNumRbsPerSymF1[nNumerology][8]);
1086                     case PHY_BW_70MHZ:  return(nNumRbsPerSymF1[nNumerology][9]);
1087                     case PHY_BW_80MHZ:  return(nNumRbsPerSymF1[nNumerology][10]);
1088                     case PHY_BW_90MHZ:  return(nNumRbsPerSymF1[nNumerology][11]);
1089                     case PHY_BW_100MHZ: return(nNumRbsPerSymF1[nNumerology][12]);
1090                 }
1091             }
1092         }
1093         else { /* if(nSub6) */
1094             if((nNumerology >= 2) && (nNumerology <= 3)) {
1095                 nNumerology -= 2;
1096                 /* F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB */
1097                 switch(nBandwidth) {
1098                     case PHY_BW_50MHZ:  return(nNumRbsPerSymF2[nNumerology][0]); break;
1099                     case PHY_BW_100MHZ: return(nNumRbsPerSymF2[nNumerology][1]); break;
1100                     case PHY_BW_200MHZ: return(nNumRbsPerSymF2[nNumerology][2]); break;
1101                     case PHY_BW_400MHZ: return(nNumRbsPerSymF2[nNumerology][3]); break;
1102                 }
1103             }
1104         }
1105
1106         return(-1);
1107     }
1108
1109     void *get_xranhandle()  { return(m_xranhandle); }
1110     void *get_timer_ctx()   { return((void *)&m_timer_ctx[0]); }
1111
1112     int get_symbol_index()  { return (xran_lib_ota_sym); }
1113
1114     bool is_running()       { return((xran_get_if_state() == XRAN_RUNNING)?true:false); }
1115
1116     enum xran_category get_rucategory()    { return(m_xranConf.ru_conf.xranCat); }
1117
1118     int get_numerology()    { return(m_xranConf.frame_conf.nNumerology); }
1119     int get_duplextype()    { return(m_xranConf.frame_conf.nFrameDuplexType); }
1120     int get_num_cc()        { return(m_xranConf.nCC); }
1121     int get_num_eaxc()      { return(m_xranConf.neAxc); }
1122     int get_num_dlrbs()     { return(m_xranConf.nDLRBs); }
1123     int get_num_ulrbs()     { return(m_xranConf.nULRBs); }
1124     int get_num_antelmtrx() { return(m_xranConf.nAntElmTRx); }
1125
1126     bool is_cpenable()      { return(m_xranInit.enableCP); };
1127     bool is_prachenable()   { return(m_xranInit.prachEnable); };
1128     bool is_dynamicsection() { return(m_xranInit.DynamicSectionEna?true:false); }
1129
1130     void get_cfg_prach(struct xran_prach_config *pCfg)
1131     {
1132         if(pCfg)
1133             memcpy(pCfg, &m_xranConf.prach_conf, sizeof(struct xran_prach_config));
1134     }
1135
1136     void get_cfg_frame(struct xran_frame_config *pCfg)
1137     {
1138         if(pCfg)
1139             memcpy(pCfg, &m_xranConf.frame_conf, sizeof(struct xran_frame_config));
1140     }
1141
1142     void get_cfg_ru(struct xran_ru_config *pCfg)
1143     {
1144         if(pCfg)
1145             memcpy(pCfg, &m_xranConf.ru_conf, sizeof(struct xran_ru_config));
1146     }
1147
1148     void get_cfg_fh(struct xran_fh_config *pCfg)
1149     {
1150         if(pCfg)
1151             memcpy(pCfg, &m_xranConf, sizeof(struct xran_fh_config));
1152     }
1153
1154 };
1155
1156
1157 /* external declaration for the instance */
1158 extern xranLibWraper *xranlib;
1159
1160
1161 #endif //XRAN_LIB_WRAP_HPP