1 /******************************************************************************
\r
3 * Copyright (c) 2019 Intel.
\r
5 * Licensed under the Apache License, Version 2.0 (the "License");
\r
6 * you may not use this file except in compliance with the License.
\r
7 * You may obtain a copy of the License at
\r
9 * http://www.apache.org/licenses/LICENSE-2.0
\r
11 * Unless required by applicable law or agreed to in writing, software
\r
12 * distributed under the License is distributed on an "AS IS" BASIS,
\r
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
14 * See the License for the specific language governing permissions and
\r
15 * limitations under the License.
\r
17 *******************************************************************************/
\r
20 * @brief XRAN layer common functionality for both lls-CU and RU as well as C-plane and
\r
22 * @file xran_common.c
\r
23 * @ingroup group_source_xran
\r
24 * @author Intel Corporation
\r
29 #include <arpa/inet.h>
\r
30 #include <sys/time.h>
\r
33 #include "xran_frame_struct.h"
\r
34 #include "xran_printf.h"
\r
36 enum nXranChBwOptions
\r
38 XRAN_BW_5_0_MHZ = 5, XRAN_BW_10_0_MHZ = 10, XRAN_BW_15_0_MHZ = 15, XRAN_BW_20_0_MHZ = 20, XRAN_BW_25_0_MHZ = 25,
\r
39 XRAN_BW_30_0_MHZ = 30, XRAN_BW_40_0_MHZ = 40, XRAN_BW_50_0_MHZ = 50, XRAN_BW_60_0_MHZ = 60, XRAN_BW_70_0_MHZ = 70,
\r
40 XRAN_BW_80_0_MHZ = 80, XRAN_BW_90_0_MHZ = 90, XRAN_BW_100_0_MHZ = 100, XRAN_BW_200_0_MHZ = 200, XRAN_BW_400_0_MHZ = 400
\r
43 // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
\r
44 static uint16_t nNumRbsPerSymF1[3][13] =
\r
46 // 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
\r
47 {25, 52, 79, 106, 133, 160, 216, 270, 0, 0, 0, 0, 0}, // Numerology 0 (15KHz)
\r
48 {11, 24, 38, 51, 65, 78, 106, 133, 162, 0, 217, 245, 273}, // Numerology 1 (30KHz)
\r
49 {0, 11, 18, 24, 31, 38, 51, 65, 79, 0, 107, 121, 135} // Numerology 2 (60KHz)
\r
52 // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
\r
53 static uint16_t nNumRbsPerSymF2[2][4] =
\r
55 // 50Mhz 100MHz 200MHz 400MHz
\r
56 {66, 132, 264, 0}, // Numerology 2 (60KHz)
\r
57 {32, 66, 132, 264} // Numerology 3 (120KHz)
\r
60 // 38.211 - Table 4.2.1
\r
61 static uint16_t nSubCarrierSpacing[5] =
\r
70 // TTI interval in us (slot duration)
\r
71 static uint16_t nTtiInterval[4] =
\r
79 // F1 Tables 38.101-1 Table F.5.3. Window length for normal CP
\r
80 static uint16_t nCpSizeF1[3][13][2] =
\r
82 // 5MHz 10MHz 15MHz 20 MHz 25 MHz 30 MHz 40 MHz 50MHz 60 MHz 70 MHz 80 MHz 90 MHz 100 MHz
\r
83 {{40, 36}, {80, 72}, {120, 108}, {160, 144}, {160, 144}, {240, 216}, {320, 288}, {320, 288}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, // Numerology 0 (15KHz)
\r
84 {{22, 18}, {44, 36}, {66, 54}, {88, 72}, {88, 72}, {132, 108}, {176, 144}, {176, 144}, {264, 216}, {264, 216}, {352, 288}, {352, 288}, {352, 288}}, // Numerology 1 (30KHz)
\r
85 { {0, 0}, {26, 18}, {39, 27}, {52, 36}, {52, 36}, {78, 54}, {104, 72}, {104, 72}, {156, 108}, {156, 108}, {208, 144}, {208, 144}, {208, 144}}, // Numerology 2 (60KHz)
\r
88 // F2 Tables 38.101-2 Table F.5.3. Window length for normal CP
\r
89 static int16_t nCpSizeF2[2][4][2] =
\r
91 // 50Mhz 100MHz 200MHz 400MHz
\r
92 { {0, 0}, {104, 72}, {208, 144}, {416, 288}}, // Numerology 2 (60KHz)
\r
93 {{68, 36}, {136, 72}, {272, 144}, {544, 288}}, // Numerology 3 (120KHz)
\r
96 static uint32_t xran_fs_max_slot_num = 8000;
\r
97 static uint32_t xran_fs_max_slot_num_SFN = 20480; /* max slot number counted as SFN is 0-1023 */
\r
98 static uint16_t xran_fs_num_slot_tdd_loop[XRAN_MAX_SECTOR_NR] = { XRAN_NUM_OF_SLOT_IN_TDD_LOOP };
\r
99 static uint16_t xran_fs_num_dl_sym_sp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
\r
100 static uint16_t xran_fs_num_ul_sym_sp[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {0};
\r
101 static uint8_t xran_fs_slot_type[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP] = {{XRAN_SLOT_TYPE_INVALID}};
\r
102 static uint8_t xran_fs_slot_symb_type[XRAN_MAX_SECTOR_NR][XRAN_NUM_OF_SLOT_IN_TDD_LOOP][XRAN_NUM_OF_SYMBOL_PER_SLOT] = {{{XRAN_SLOT_TYPE_INVALID}}};
\r
103 static float xran_fs_ul_rate[XRAN_MAX_SECTOR_NR] = {0.0};
\r
104 static float xran_fs_dl_rate[XRAN_MAX_SECTOR_NR] = {0.0};
\r
106 extern uint16_t xran_max_frame;
\r
108 uint32_t xran_fs_get_tti_interval(uint8_t nMu)
\r
112 return nTtiInterval[nMu];
\r
116 printf("ERROR: %s Mu[%d] is not valid, setting to 0\n",__FUNCTION__, nMu);
\r
117 return nTtiInterval[0];
\r
121 uint32_t xran_fs_get_scs(uint8_t nMu)
\r
125 return nSubCarrierSpacing[nMu];
\r
129 printf("ERROR: %s Mu[%d] is not valid\n",__FUNCTION__, nMu);
\r
135 //-------------------------------------------------------------------------------------------
\r
136 /** @ingroup group_nr5g_source_phy_common
\r
138 * @param[in] nNumerology - Numerology determine sub carrier spacing, Value: 0->4 0: 15khz, 1: 30khz, 2: 60khz 3: 120khz, 4: 240khz
\r
139 * @param[in] nBandwidth - Carrier bandwidth for in MHz. Value: 5->400
\r
140 * @param[in] nAbsFrePointA - Abs Freq Point A of the Carrier Center Frequency for in KHz Value: 450000->52600000
\r
142 * @return Number of RBs in cell
\r
145 * Returns number of RBs based on 38.101-1 and 38.101-2 for the cell
\r
148 //-------------------------------------------------------------------------------------------
\r
149 uint16_t xran_fs_get_num_rbs(uint32_t nNumerology, uint32_t nBandwidth, uint32_t nAbsFrePointA)
\r
151 uint32_t error = 1;
\r
152 uint16_t numRBs = 0;
\r
154 if (nAbsFrePointA <= 6000000)
\r
156 // F1 Tables 38.101-1 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
\r
157 if (nNumerology < 3)
\r
161 case XRAN_BW_5_0_MHZ:
\r
162 numRBs = nNumRbsPerSymF1[nNumerology][0];
\r
165 case XRAN_BW_10_0_MHZ:
\r
166 numRBs = nNumRbsPerSymF1[nNumerology][1];
\r
169 case XRAN_BW_15_0_MHZ:
\r
170 numRBs = nNumRbsPerSymF1[nNumerology][2];
\r
173 case XRAN_BW_20_0_MHZ:
\r
174 numRBs = nNumRbsPerSymF1[nNumerology][3];
\r
177 case XRAN_BW_25_0_MHZ:
\r
178 numRBs = nNumRbsPerSymF1[nNumerology][4];
\r
181 case XRAN_BW_30_0_MHZ:
\r
182 numRBs = nNumRbsPerSymF1[nNumerology][5];
\r
185 case XRAN_BW_40_0_MHZ:
\r
186 numRBs = nNumRbsPerSymF1[nNumerology][6];
\r
189 case XRAN_BW_50_0_MHZ:
\r
190 numRBs = nNumRbsPerSymF1[nNumerology][7];
\r
193 case XRAN_BW_60_0_MHZ:
\r
194 numRBs = nNumRbsPerSymF1[nNumerology][8];
\r
197 case XRAN_BW_70_0_MHZ:
\r
198 numRBs = nNumRbsPerSymF1[nNumerology][9];
\r
201 case XRAN_BW_80_0_MHZ:
\r
202 numRBs = nNumRbsPerSymF1[nNumerology][10];
\r
205 case XRAN_BW_90_0_MHZ:
\r
206 numRBs = nNumRbsPerSymF1[nNumerology][11];
\r
209 case XRAN_BW_100_0_MHZ:
\r
210 numRBs = nNumRbsPerSymF1[nNumerology][12];
\r
221 if ((nNumerology >= 2) && (nNumerology <= 3))
\r
223 // F2 Tables 38.101-2 Table 5.3.2-1. Maximum transmission bandwidth configuration NRB
\r
226 case XRAN_BW_50_0_MHZ:
\r
227 numRBs = nNumRbsPerSymF2[nNumerology-2][0];
\r
230 case XRAN_BW_100_0_MHZ:
\r
231 numRBs = nNumRbsPerSymF2[nNumerology-2][1];
\r
234 case XRAN_BW_200_0_MHZ:
\r
235 numRBs = nNumRbsPerSymF2[nNumerology-2][2];
\r
238 case XRAN_BW_400_0_MHZ:
\r
239 numRBs = nNumRbsPerSymF2[nNumerology-2][3];
\r
252 printf("ERROR: %s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA);
\r
256 printf("%s: nNumerology[%d] nBandwidth[%d] nAbsFrePointA[%d] numRBs[%d]\n",__FUNCTION__, nNumerology, nBandwidth, nAbsFrePointA, numRBs);
\r
262 //-------------------------------------------------------------------------------------------
\r
263 /** @ingroup phy_cal_nrarfcn
\r
265 * @param[in] center frequency
\r
270 * This calculates NR-ARFCN value according to center frequency
\r
273 //-------------------------------------------------------------------------------------------
\r
274 uint32_t xran_fs_cal_nrarfcn(uint32_t nCenterFreq)
\r
276 uint32_t nDeltaFglobal,nFoffs,nNoffs;
\r
277 uint32_t nNRARFCN = 0;
\r
279 if(nCenterFreq > 0 && nCenterFreq < 3000*1000)
\r
285 else if(nCenterFreq >= 3000*1000 && nCenterFreq < 24250*1000)
\r
287 nDeltaFglobal = 15;
\r
288 nFoffs = 3000*1000;
\r
291 else if(nCenterFreq >= 24250*1000 && nCenterFreq <= 100000*1000)
\r
293 nDeltaFglobal = 60;
\r
299 printf("@@@@ incorrect center frerquency %d\n",nCenterFreq);
\r
303 nNRARFCN = ((nCenterFreq - nFoffs)/nDeltaFglobal) + nNoffs;
\r
305 printf("%s: nCenterFreq[%d] nDeltaFglobal[%d] nFoffs[%d] nNoffs[%d] nNRARFCN[%d]\n", __FUNCTION__, nCenterFreq, nDeltaFglobal, nFoffs, nNoffs, nNRARFCN);
\r
309 uint32_t xran_fs_slot_limit_init(int32_t tti_interval_us)
\r
311 xran_fs_max_slot_num = (1000/tti_interval_us)*1000;
\r
312 xran_fs_max_slot_num_SFN = (1000/tti_interval_us)*(xran_max_frame+1)*10;
\r
313 return xran_fs_max_slot_num;
\r
316 uint32_t xran_fs_get_max_slot(void)
\r
318 return xran_fs_max_slot_num;
\r
321 uint32_t xran_fs_get_max_slot_SFN(void)
\r
323 return xran_fs_max_slot_num_SFN;
\r
326 int32_t xran_fs_slot_limit(int32_t nSfIdx)
\r
328 while (nSfIdx < 0) {
\r
329 nSfIdx += xran_fs_max_slot_num;
\r
332 while (nSfIdx >= xran_fs_max_slot_num) {
\r
333 nSfIdx -= xran_fs_max_slot_num;
\r
339 void xran_fs_clear_slot_type(uint32_t nPhyInstanceId)
\r
341 xran_fs_ul_rate[nPhyInstanceId] = 0.0;
\r
342 xran_fs_dl_rate[nPhyInstanceId] = 0.0;
\r
343 xran_fs_num_slot_tdd_loop[nPhyInstanceId] = 1;
\r
346 int32_t xran_fs_set_slot_type(uint32_t nPhyInstanceId, uint32_t nFrameDuplexType, uint32_t nTddPeriod, struct xran_slot_config* psSlotConfig)
\r
348 uint32_t nSlotNum, nSymNum, nVal, i, j;
\r
349 uint32_t numDlSym, numUlSym, numGuardSym;
\r
350 uint32_t numDlSlots = 0, numUlSlots = 0, numSpDlSlots = 0, numSpUlSlots = 0, numSpSlots = 0;
\r
351 char sSlotPattern[XRAN_SLOT_TYPE_LAST][10] = {"IN\0", "DL\0", "UL\0", "SP\0", "FD\0"};
\r
353 // nPhyInstanceId Carrier ID
\r
354 // nFrameDuplexType 0 = FDD 1 = TDD
\r
355 // nTddPeriod Tdd Periodicity
\r
356 // psSlotConfig[80] Slot Config Structure for nTddPeriod Slots
\r
358 xran_fs_ul_rate[nPhyInstanceId] = 0.0;
\r
359 xran_fs_dl_rate[nPhyInstanceId] = 0.0;
\r
360 xran_fs_num_slot_tdd_loop[nPhyInstanceId] = nTddPeriod;
\r
362 for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
\r
364 xran_fs_slot_type[nPhyInstanceId][i] = XRAN_SLOT_TYPE_INVALID;
\r
365 xran_fs_num_dl_sym_sp[nPhyInstanceId][i] = 0;
\r
366 xran_fs_num_ul_sym_sp[nPhyInstanceId][i] = 0;
\r
369 if (nFrameDuplexType == XRAN_FDD)
\r
371 for (i = 0; i < XRAN_NUM_OF_SLOT_IN_TDD_LOOP; i++)
\r
373 xran_fs_slot_type[nPhyInstanceId][i] = XRAN_SLOT_TYPE_FDD;
\r
374 for(j = 0; j < XRAN_NUM_OF_SYMBOL_PER_SLOT; j++)
\r
375 xran_fs_slot_symb_type[nPhyInstanceId][i][j] = XRAN_SYMBOL_TYPE_FDD;
\r
377 xran_fs_num_slot_tdd_loop[nPhyInstanceId] = 1;
\r
378 xran_fs_dl_rate[nPhyInstanceId] = 1.0;
\r
379 xran_fs_ul_rate[nPhyInstanceId] = 1.0;
\r
383 for (nSlotNum = 0; nSlotNum < nTddPeriod; nSlotNum++)
\r
388 for (nSymNum = 0; nSymNum < XRAN_NUM_OF_SYMBOL_PER_SLOT; nSymNum++)
\r
390 switch(psSlotConfig[nSlotNum].nSymbolType[nSymNum])
\r
392 case XRAN_SYMBOL_TYPE_DL:
\r
394 xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_DL;
\r
396 case XRAN_SYMBOL_TYPE_GUARD:
\r
397 xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_GUARD;
\r
401 xran_fs_slot_symb_type[nPhyInstanceId][nSlotNum][nSymNum] = XRAN_SYMBOL_TYPE_UL;
\r
407 print_dbg("nSlotNum[%d] : numDlSym[%d] numGuardSym[%d] numUlSym[%d] ", nSlotNum, numDlSym, numGuardSym, numUlSym);
\r
409 if ((numUlSym == 0) && (numGuardSym == 0))
\r
411 xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_DL;
\r
413 print_dbg("XRAN_SLOT_TYPE_DL\n");
\r
415 else if ((numDlSym == 0) && (numGuardSym == 0))
\r
417 xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_UL;
\r
419 print_dbg("XRAN_SLOT_TYPE_UL\n");
\r
423 xran_fs_slot_type[nPhyInstanceId][nSlotNum] = XRAN_SLOT_TYPE_SP;
\r
425 print_dbg("XRAN_SLOT_TYPE_SP\n");
\r
430 xran_fs_num_dl_sym_sp[nPhyInstanceId][nSlotNum] = numDlSym;
\r
435 xran_fs_num_ul_sym_sp[nPhyInstanceId][nSlotNum] = numUlSym;
\r
438 print_dbg(" numDlSlots[%d] numUlSlots[%d] numSpSlots[%d] numSpDlSlots[%d] numSpUlSlots[%d]\n", numDlSlots, numUlSlots, numSpSlots, numSpDlSlots, numSpUlSlots);
\r
441 xran_fs_dl_rate[nPhyInstanceId] = (float)(numDlSlots + numSpDlSlots) / (float)nTddPeriod;
\r
442 xran_fs_ul_rate[nPhyInstanceId] = (float)(numUlSlots + numSpUlSlots) / (float)nTddPeriod;
\r
445 print_dbg("%s: nPhyInstanceId[%d] nFrameDuplexType[%d], nTddPeriod[%d]\n",
\r
446 __FUNCTION__, nPhyInstanceId, nFrameDuplexType, nTddPeriod);
\r
448 print_dbg("DLRate[%f] ULRate[%f]\n", xran_fs_dl_rate[nPhyInstanceId], xran_fs_ul_rate[nPhyInstanceId]);
\r
450 nVal = (xran_fs_num_slot_tdd_loop[nPhyInstanceId] < 10) ? xran_fs_num_slot_tdd_loop[nPhyInstanceId] : 10;
\r
452 print_dbg("SlotPattern:\n");
\r
453 print_dbg("Slot: ");
\r
454 for (nSlotNum = 0; nSlotNum < nVal; nSlotNum++)
\r
456 print_dbg("%d ", nSlotNum);
\r
460 print_dbg(" %3d ", 0);
\r
461 for (nSlotNum = 0, i = 0; nSlotNum < xran_fs_num_slot_tdd_loop[nPhyInstanceId]; nSlotNum++)
\r
463 print_dbg("%s ", sSlotPattern[xran_fs_slot_type[nPhyInstanceId][nSlotNum]]);
\r
465 if ((i == 10) && ((nSlotNum+1) < xran_fs_num_slot_tdd_loop[nPhyInstanceId]))
\r
468 print_dbg(" %3d ", nSlotNum);
\r
477 int32_t xran_fs_get_slot_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nType)
\r
479 int32_t nSfIdxMod, nSfType, ret = 0;
\r
481 nSfIdxMod = xran_fs_slot_limit(nSlotdx) % ((xran_fs_num_slot_tdd_loop[nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[nCellIdx]: 1);
\r
482 nSfType = xran_fs_slot_type[nCellIdx][nSfIdxMod];
\r
484 if (nSfType == nType)
\r
488 else if (nSfType == XRAN_SLOT_TYPE_SP)
\r
490 if ((nType == XRAN_SLOT_TYPE_DL) && xran_fs_num_dl_sym_sp[nCellIdx][nSfIdxMod])
\r
495 if ((nType == XRAN_SLOT_TYPE_UL) && xran_fs_num_ul_sym_sp[nCellIdx][nSfIdxMod])
\r
500 else if (nSfType == XRAN_SLOT_TYPE_FDD)
\r
508 int32_t xran_fs_get_symbol_type(int32_t nCellIdx, int32_t nSlotdx, int32_t nSymbIdx)
\r
510 int32_t nSfIdxMod, nSfType, ret = 0;
\r
512 nSfIdxMod = xran_fs_slot_limit(nSlotdx) % ((xran_fs_num_slot_tdd_loop[nCellIdx] > 0) ? xran_fs_num_slot_tdd_loop[nCellIdx]: 1);
\r
514 return xran_fs_slot_symb_type[nCellIdx][nSfIdxMod][nSymbIdx];
\r