[JIRA ID: ODUHIGH-242] RB configuration for Ue Context Setup for RLC
[o-du/l2.git] / src / 5gnrmac / mac_ue_mgr.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
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 /* This file contains UE management handling functionality for MAC */
20
21 /* header include files (.h) */
22 #include "common_def.h"
23 #include "lrg.h"
24 #include "lrg.x"
25 #include "du_app_mac_inf.h"
26 #include "mac_sch_interface.h"
27 #include "lwr_mac_upr_inf.h"
28 #include "mac.h"
29 #include "mac_utils.h"
30
31 /* function pointers for packing slot ind from mac to sch */
32 MacSchUeCreateReqFunc macSchUeCreateReqOpts[] =
33 {
34    packMacSchUeCreateReq,    /* packing for loosely coupled */
35    MacSchUeCreateReq,        /* packing for tightly coupled */
36    packMacSchUeCreateReq     /* packing for light weight loosely coupled */
37 };
38
39 MacDuUeCfgRspFunc MacDuUeCfgRspOpts[] =
40 {
41    packDuMacUeCfgRsp,   /* packing for loosely coupled */
42    DuProcMacUeCfgRsp,   /* packing for tightly coupled */
43    packDuMacUeCfgRsp   /* packing for light weight loosly coupled */
44 };
45
46 MacSchUeReconfigReqFunc macSchUeReconfigReqOpts[] =
47 {
48    packMacSchUeReconfigReq,    /* packing for loosely coupled */
49    MacSchUeReconfigReq,        /* packing for tightly coupled */
50    packMacSchUeReconfigReq     /* packing for light weight loosely coupled */
51 };
52
53 /*******************************************************************
54  *
55  * @brief Fills mac cell group config to be sent to scheduler
56  *
57  * @details
58  *
59  *    Function : fillMacCellGroupCfg
60  *
61  *    Functionality: Fills mac cell group config to be sent to sch
62  *
63  * @params[in] macCellGrp : mac cell group config at MAC
64  *             *macCellGrpCfg : mac cell group cfg to be filled
65  * @return ROK     - success
66  *         RFAILED - failure
67  *
68  * ****************************************************************/
69 uint8_t fillMacCellGroupCfg(MacCellGrpCfg macCellGrp, SchMacCellGrpCfg  *macCellGrpCfg)
70 {
71    uint8_t           idx;
72    SchSchedReqCfg    *schedReqCfg;
73    SchTagCfg         *tagCfg;
74
75    /* Copy scheduling request config */
76    schedReqCfg = &macCellGrpCfg->schedReqCfg;
77    schedReqCfg->addModListCount = macCellGrp.schReqCfg.addModListCount;
78    if(schedReqCfg->addModListCount > MAX_NUM_SR_CFG_PER_CELL_GRP)
79    {
80       DU_LOG("\nMAC : Scheduling Request Add/Mod Count %d exceeds max limit %d", \
81             schedReqCfg->addModListCount, MAX_NUM_SR_CFG_PER_CELL_GRP);
82       return RFAILED;
83    }
84    for(idx = 0; idx < schedReqCfg->addModListCount; idx++)
85    {
86       schedReqCfg->addModList[idx].schedReqId = \
87          macCellGrp.schReqCfg.addModList[idx].schedReqId;
88       schedReqCfg->addModList[idx].srProhibitTmr = \
89          macCellGrp.schReqCfg.addModList[idx].srProhibitTmr;
90       schedReqCfg->addModList[idx].srTransMax = \
91          macCellGrp.schReqCfg.addModList[idx].srTransMax;
92    }
93    schedReqCfg->relListCount = macCellGrp.schReqCfg.relListCount;
94
95    /* copy TAG config */
96    tagCfg = &macCellGrpCfg->tagCfg;
97    tagCfg->addModListCount = macCellGrp.tagCfg.addModListCount;
98    if(tagCfg->addModListCount > MAX_NUM_TAGS)
99    {
100       DU_LOG("\nMAC : Scheduling Request Add/Mod Count %d exceeds max limit %d", \
101             tagCfg->addModListCount, MAX_NUM_TAGS);
102       return RFAILED;
103    }
104    for(idx = 0; idx < tagCfg->addModListCount; idx++)
105    {
106       tagCfg->addModList[idx].tagId = \
107          macCellGrp.tagCfg.addModList[idx].tagId;
108       tagCfg->addModList[idx].timeAlignmentTmr = \
109          macCellGrp.tagCfg.addModList[idx].timeAlignTimer;
110    }
111    tagCfg->relListCount = macCellGrp.tagCfg.relListCount;
112
113    /* Copy PHR config */
114    if(macCellGrp.phrCfgSetupPres)
115    {
116       macCellGrpCfg->phrCfg.periodicTmr = macCellGrp.phrCfg.periodicTimer;
117       macCellGrpCfg->phrCfg.prohibitTmr =  macCellGrp.phrCfg.prohibitTimer;
118       macCellGrpCfg->phrCfg.txpowerFactorChange = macCellGrp.phrCfg.txPowerFactor;
119       macCellGrpCfg->phrCfg.multiplePhr = macCellGrp.phrCfg.multiplePHR;
120       macCellGrpCfg->phrCfg.dummy = macCellGrp.phrCfg.dummy;
121       macCellGrpCfg->phrCfg.type2OtherCell = macCellGrp.phrCfg.phrType2OtherCell;
122       macCellGrpCfg->phrCfg.modeOtherCG = macCellGrp.phrCfg.phrOtherCG;
123    }
124
125    return ROK;
126 }
127
128 /*******************************************************************
129  *
130  * @brief Fills phy cell group config to be sent to scheduler
131  *
132  * @details
133  *
134  *    Function : fillPhyCellGroupCfg
135  *
136  *    Functionality: Fills phy cell group config to be sent to sch
137  *
138  * @params[in] macUeCfg : Phy cell group config at MAC
139  *             *schPhyCellGrp : phy cell group config to be filled
140  * @return ROK     - success
141  *         RFAILED - failure
142  *
143  * ****************************************************************/
144 uint8_t fillPhyCellGroupCfg(PhyCellGrpCfg macUeCfg, SchPhyCellGrpCfg *schPhyCellGrp)
145 {
146    schPhyCellGrp->pdschHarqAckCodebook = macUeCfg.pdschHarqAckCodebook;
147    schPhyCellGrp->pNrFr1 = macUeCfg.pNrFr1;
148
149    return ROK;
150 }
151
152 /*******************************************************************
153  *
154  * @brief Fills PDSCh serving cell config to send to scheduler
155  *
156  * @details
157  *
158  *    Function : fillPdschServCellCfg 
159  *
160  *    Functionality: Fills PDSCh serving cell config to send to scheduler
161  *
162  * @params[in] macPdschCfg : Pdsch serving cell config at MAC
163  *             *schPdschCfg : Pdsch serving cell config to be filled
164  * @return ROK     - success
165  *         RFAILED - failure
166  *
167  * ****************************************************************/
168 uint8_t fillPdschServCellCfg(PdschServCellCfg macPdschCfg, SchPdschServCellCfg *schPdschCfg) 
169 {
170    if(macPdschCfg.maxMimoLayers)
171    {
172       if(!schPdschCfg->maxMimoLayers)
173       {
174          MAC_ALLOC_SHRABL_BUF(schPdschCfg->maxMimoLayers, sizeof(uint8_t));
175          if(!schPdschCfg->maxMimoLayers)
176          {
177             DU_LOG("\nMAC :Memory Alloc MimoLayers Failed at fillPdschServCellCfg()");
178             return RFAILED;
179          }
180       }
181       *schPdschCfg->maxMimoLayers = *macPdschCfg.maxMimoLayers;
182    }
183    else
184    {
185       schPdschCfg->maxMimoLayers = NULLP;
186    }
187
188    schPdschCfg->numHarqProcForPdsch = \
189       macPdschCfg.numHarqProcForPdsch;
190
191    if(macPdschCfg.maxCodeBlkGrpPerTb)
192    {
193       if(!schPdschCfg->maxCodeBlkGrpPerTb)
194       {
195          MAC_ALLOC_SHRABL_BUF(schPdschCfg->maxCodeBlkGrpPerTb, sizeof(SchMaxCodeBlkGrpPerTB));
196          if(!schPdschCfg->maxCodeBlkGrpPerTb)
197          {
198             DU_LOG("\nMAC :Memory Alloc for code Block Failed at fillPdschServCellCfg()");
199             return RFAILED;
200          }
201       }
202       *schPdschCfg->maxCodeBlkGrpPerTb = *macPdschCfg.maxCodeBlkGrpPerTb;
203    }
204    else
205    {
206       schPdschCfg->maxCodeBlkGrpPerTb = NULLP;
207    }
208
209    if(macPdschCfg.codeBlkGrpFlushInd)
210    {
211       if(!schPdschCfg->codeBlkGrpFlushInd)
212       {
213          MAC_ALLOC_SHRABL_BUF(schPdschCfg->codeBlkGrpFlushInd, sizeof(bool));
214          if(!schPdschCfg->codeBlkGrpFlushInd)
215          {
216             DU_LOG("\nMAC :Memory Alloc for Flush Ind Failed at fillPdschServCellCfg()");
217             return RFAILED;
218          }
219       }
220       *schPdschCfg->codeBlkGrpFlushInd = *macPdschCfg.codeBlkGrpFlushInd;
221    }
222    else
223    {
224       schPdschCfg->codeBlkGrpFlushInd = NULLP;
225    }
226
227    if(macPdschCfg.xOverhead)
228    {
229       if(!schPdschCfg->xOverhead)
230       {
231          MAC_ALLOC_SHRABL_BUF(schPdschCfg->xOverhead, sizeof(SchPdschXOverhead));
232          if(!schPdschCfg->xOverhead)
233          {
234             DU_LOG("\nMAC :Memory Alloc for xOverHead Failed at fillPdschServCellCfg()");
235             return RFAILED;
236          }
237       }
238       *schPdschCfg->xOverhead = *macPdschCfg.xOverhead;
239    }
240    else
241    {
242       schPdschCfg->xOverhead = NULLP;
243    }
244
245    return ROK;
246 }
247
248 /*******************************************************************
249  *
250  * @brief Fills PUSCH cofig in initial UL BWP config for SCH UE Cfg
251  *
252  * @details
253  *
254  *    Function : fillInitalUlBwpPuschCfg
255  *
256  *    Functionality:
257  *       Fills PUSCH cofig in initial UL BWP config for SCH UE Cfg
258  *
259  * @params[in] macPuschCfg : Initial UL-BWP PUSCH cfg at MAC
260  *             schPuschCfg : Initial UL-BWP PUSCH cfg to be filled
261  * @return ROK     - success
262  *         RFAILED - failure
263  *
264  * ****************************************************************/
265 uint8_t fillInitalUlBwpPuschCfg(PuschCfg macPuschCfg, SchPuschCfg *schPuschCfg)
266 {
267    uint8_t   idx;
268
269    schPuschCfg->dataScramblingId = macPuschCfg.dataScramblingId;
270    schPuschCfg->dmrsUlCfgForPuschMapTypeA.addPos = \
271       macPuschCfg.dmrsUlCfgForPuschMapTypeA.addPos;
272    schPuschCfg->dmrsUlCfgForPuschMapTypeA.transPrecodDisabled.scramblingId0 = \
273       macPuschCfg.dmrsUlCfgForPuschMapTypeA.transPrecodDisabled.scramblingId0;
274    schPuschCfg->resourceAllocType = macPuschCfg.resourceAllocType;
275
276    schPuschCfg->numTimeDomRsrcAlloc = macPuschCfg.numTimeDomRsrcAlloc;
277    if(schPuschCfg->numTimeDomRsrcAlloc > MAX_NUM_UL_ALLOC)
278    {
279       DU_LOG("\nMAC : Number of Time domain resource allocation [%d] exceeds max limit [%d]",\
280             schPuschCfg->numTimeDomRsrcAlloc, MAX_NUM_UL_ALLOC);
281       return RFAILED;
282    }    
283    for(idx = 0; idx < schPuschCfg->numTimeDomRsrcAlloc; idx++)
284    {
285       schPuschCfg->timeDomRsrcAllocList[idx].k2 = \
286          macPuschCfg.timeDomRsrcAllocList[idx].k2;
287       schPuschCfg->timeDomRsrcAllocList[idx].mappingType = \
288          macPuschCfg.timeDomRsrcAllocList[idx].mappingType;
289       schPuschCfg->timeDomRsrcAllocList[idx].startSymbol = \
290          macPuschCfg.timeDomRsrcAllocList[idx].startSymbol; 
291       schPuschCfg->timeDomRsrcAllocList[idx].symbolLength = \
292          macPuschCfg.timeDomRsrcAllocList[idx].symbolLength;
293    }
294
295    schPuschCfg->transformPrecoder = macPuschCfg.transformPrecoder;
296    return ROK;
297 }
298
299 /*******************************************************************
300  *
301  * @brief Fills initail UL BWP config to send to scheduler
302  *
303  * @details
304  *
305  *    Function : fillInitialUlBwp
306  *
307  *    Functionality: Fills initail UL BWP config to send to sch
308  *
309  * @params[in] macInitUlBwp : Initial UL BWP cfg at MAC
310  *             schInitUlBwp : Initial UL BWP cfg to be filled
311  * @return ROK     - success
312  *         RFAILED - failure
313  *
314  * ****************************************************************/
315 uint8_t fillInitialUlBwp(InitialUlBwp macInitUlBwp, SchInitialUlBwp *schInitUlBwp)
316 {
317    schInitUlBwp->pucchCfgPres = macInitUlBwp.pucchPresent;
318    if(schInitUlBwp->pucchCfgPres)
319    {
320       /* TODO : Optional parameter */
321    }
322
323    schInitUlBwp->puschCfgPres = macInitUlBwp.puschPresent;
324    if(schInitUlBwp->puschCfgPres)
325    {
326       if(fillInitalUlBwpPuschCfg(macInitUlBwp.puschCfg, &schInitUlBwp->puschCfg) != ROK)
327       {
328          DU_LOG("\nMAC : fillInitalUlBwpPuschCfg() failed");
329          return RFAILED;
330       }
331    }
332    return ROK;
333 }
334
335 /*******************************************************************
336  *
337  * @brief Fill PDCCH cfg in Initial DL BWP for UE Cfg in Scheduler
338  *
339  * @details
340  *
341  *    Function : fillInitDlBwpPdcchCfg
342  *
343  *    Functionality:
344  *        Fill PDCCH cfg in Initial DL BWP for UE Cfg in Scheduler
345  *
346  * @params[in] macPdcchCfg : Inital DL BWP PDCCH cfg in MAC
347  *             schPdcchCfg : Inital DL BWP PDCCH cfg to be filled
348  * @return ROK     - success
349  *         RFAILED - failure
350  *
351  * ****************************************************************/
352 uint8_t fillInitDlBwpPdcchCfg(PdcchConfig macPdcchCfg, SchPdcchConfig *schPdcchCfg)
353 {
354    uint8_t idx;
355
356    /* Fill CORESET info */
357    schPdcchCfg->numCRsetToAddMod = macPdcchCfg.numCRsetToAddMod;
358    if(schPdcchCfg->numCRsetToAddMod > MAX_NUM_CRSET)
359    {
360       DU_LOG("\nMAC : Number of CORESET to ADD/MOD [%d] exceeds max limit [%d]",\
361             schPdcchCfg->numCRsetToAddMod, MAX_NUM_CRSET);
362       return RFAILED;
363    }
364
365    for(idx = 0; idx < schPdcchCfg->numCRsetToAddMod; idx++)
366    {
367       schPdcchCfg->cRSetToAddModList[idx].cRSetId = \
368          macPdcchCfg.cRSetToAddModList[idx].cRSetId;
369       memcpy(&schPdcchCfg->cRSetToAddModList[idx].freqDomainRsrc,\
370          &macPdcchCfg.cRSetToAddModList[idx].freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
371       schPdcchCfg->cRSetToAddModList[idx].duration = \
372          macPdcchCfg.cRSetToAddModList[idx].duration;
373       schPdcchCfg->cRSetToAddModList[idx].cceRegMappingType = \
374          macPdcchCfg.cRSetToAddModList[idx].cceRegMappingType;
375       schPdcchCfg->cRSetToAddModList[idx].precoderGranularity = \
376          macPdcchCfg.cRSetToAddModList[idx].precoderGranularity;
377       schPdcchCfg->cRSetToAddModList[idx].dmrsScramblingId = \
378          macPdcchCfg.cRSetToAddModList[idx].dmrsScramblingId;
379    }
380
381    schPdcchCfg->numCRsetToRel = macPdcchCfg.numCRsetToRel;
382    if(schPdcchCfg->numCRsetToAddMod > MAX_NUM_CRSET)
383    {
384       DU_LOG("\nMAC : Number of CORESET to release [%d] exceeds max limit [%d]",\
385             schPdcchCfg->numCRsetToRel, MAX_NUM_CRSET);
386       return RFAILED;
387    }
388
389    for(idx = 0; idx < schPdcchCfg->numCRsetToRel; idx++)
390    {
391       /* TODO */
392    }
393
394    /* Fill Search space info */
395    schPdcchCfg->numSearchSpcToAddMod = macPdcchCfg.numSearchSpcToAddMod;
396    if(schPdcchCfg->numSearchSpcToAddMod > MAX_NUM_SEARCH_SPC)
397    {
398       DU_LOG("\nMAC : Number of search space to ADD/MOD [%d] exceeds max [%d]", \
399             schPdcchCfg->numSearchSpcToAddMod, MAX_NUM_SEARCH_SPC);
400       return RFAILED;
401    }
402    for(idx = 0; idx < schPdcchCfg->numSearchSpcToAddMod; idx++)
403    {
404       schPdcchCfg->searchSpcToAddModList[idx].searchSpaceId = \
405          macPdcchCfg.searchSpcToAddModList[idx].searchSpaceId;
406       schPdcchCfg->searchSpcToAddModList[idx].cRSetId = \
407          macPdcchCfg.searchSpcToAddModList[idx].cRSetId;
408       schPdcchCfg->searchSpcToAddModList[idx].mSlotPeriodicityAndOffset = \
409          macPdcchCfg.searchSpcToAddModList[idx].mSlotPeriodicityAndOffset;
410       memcpy(&schPdcchCfg->searchSpcToAddModList[idx].mSymbolsWithinSlot,
411          &macPdcchCfg.searchSpcToAddModList[idx].mSymbolsWithinSlot, \
412          MONITORING_SYMB_WITHIN_SLOT_SIZE);
413       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel1 = \
414          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel1;
415       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel2 = \
416          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel2;
417       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel4 = \
418          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel4;
419       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel8 = \
420          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel8;
421       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel16 = \
422          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel16;
423       schPdcchCfg->searchSpcToAddModList[idx].searchSpaceType = \
424          macPdcchCfg.searchSpcToAddModList[idx].searchSpaceType;
425       schPdcchCfg->searchSpcToAddModList[idx].ueSpecificDciFormat = \
426          macPdcchCfg.searchSpcToAddModList[idx].ueSpecificDciFormat;
427    }
428
429    schPdcchCfg->numSearchSpcToRel = macPdcchCfg.numSearchSpcToRel;
430    if(schPdcchCfg->numSearchSpcToRel > MAX_NUM_SEARCH_SPC)
431    {
432       DU_LOG("\nMAC : Number of search space to release [%d] exceeds max [%d]", \
433             schPdcchCfg->numSearchSpcToRel, MAX_NUM_SEARCH_SPC);
434       return RFAILED;
435    }
436    for(idx = 0; idx < schPdcchCfg->numSearchSpcToRel; idx++)
437    {
438       /* TODO */
439    }
440
441    return ROK;
442 }
443
444 /*******************************************************************
445  *
446  * @brief Fill PDSCH cfg in Initial DL BWP for UE Cfg in Scheduler
447  *
448  * @details
449  *
450  *    Function : fillInitDlBwpPdschCfg
451  *
452  *    Functionality:
453  *        Fill PDSCH cfg in Initial DL BWP for UE Cfg in Scheduler
454  *
455  * @params[in] macPdschCfg : Inital DL BWP PDSCH cfg at  MAC
456  *             schPdschCfg : Inital DL BWP PDSCH cfg to be filled
457  * @return ROK     - success
458  *         RFAILED - failure
459  *
460  * ****************************************************************/
461 uint8_t fillInitDlBwpPdschCfg(PdschConfig macPdschCfg, SchPdschConfig *schPdschCfg)
462 {
463    uint8_t   idx;
464
465    schPdschCfg->dmrsDlCfgForPdschMapTypeA.addPos = \
466        macPdschCfg.dmrsDlCfgForPdschMapTypeA.addPos;
467    schPdschCfg->resourceAllocType = macPdschCfg.resourceAllocType;
468    schPdschCfg->numTimeDomRsrcAlloc = macPdschCfg.numTimeDomRsrcAlloc;
469    if(schPdschCfg->numTimeDomRsrcAlloc > MAX_NUM_DL_ALLOC)
470    {
471       DU_LOG("\nMAC : Number of time domain resource allocation [%d], exceeds\
472             max limit [%d]", schPdschCfg->numTimeDomRsrcAlloc, MAX_NUM_DL_ALLOC);
473       return RFAILED;
474    }
475
476    for(idx = 0; idx < schPdschCfg->numTimeDomRsrcAlloc; idx++)
477    {
478       schPdschCfg->timeDomRsrcAllociList[idx].mappingType = \
479          macPdschCfg.timeDomRsrcAllociList[idx].mappingType;
480       schPdschCfg->timeDomRsrcAllociList[idx].startSymbol = \
481          macPdschCfg.timeDomRsrcAllociList[idx].startSymbol;
482       schPdschCfg->timeDomRsrcAllociList[idx].symbolLength = \
483          macPdschCfg.timeDomRsrcAllociList[idx].symbolLength;
484    }
485
486    schPdschCfg->rbgSize = macPdschCfg.rbgSize;
487    schPdschCfg->numCodeWordsSchByDci = macPdschCfg.numCodeWordsSchByDci;
488    schPdschCfg->bundlingType = macPdschCfg.bundlingType;
489    if(schPdschCfg->bundlingType == STATIC_BUNDLING_TYPE)
490    {
491       schPdschCfg->bundlingInfo.SchStaticBundling.size  = macPdschCfg.bundlingInfo.StaticBundling.size;
492    }
493    else if(schPdschCfg->bundlingType == DYNAMIC_BUNDLING_TYPE)
494    {
495       schPdschCfg->bundlingInfo.SchDynamicBundling.sizeSet1 = macPdschCfg.bundlingInfo.DynamicBundling.sizeSet1;
496       schPdschCfg->bundlingInfo.SchDynamicBundling.sizeSet2 = macPdschCfg.bundlingInfo.DynamicBundling.sizeSet2;
497    }
498    return ROK;
499 }
500
501 /*******************************************************************
502  *
503  * @brief Fill Initial DL BWP for SCH UE config
504  *
505  * @details
506  *
507  *    Function : fillInitialDlBwp
508  *
509  *    Functionality: Fill Initial DL BWP for SCH UE config
510  *
511  * @params[in] macInitDlBwp : Inital DL BWP cfg at MAC
512  *             schInitDlBwp : Inital DL BWP cfg to be filled
513  * @return ROK     - success
514  *         RFAILED - failure
515  *
516  * ****************************************************************/
517 uint8_t fillInitialDlBwp(InitialDlBwp macInitDlBwp, SchInitalDlBwp *schInitDlBwp)
518 {
519    schInitDlBwp->pdcchCfgPres = macInitDlBwp.pdcchPresent;
520    if(schInitDlBwp->pdcchCfgPres)
521    {
522       if(fillInitDlBwpPdcchCfg(macInitDlBwp.pdcchCfg, &schInitDlBwp->pdcchCfg) != ROK)
523       {
524          DU_LOG("\nMAC : fillInitDlBwpPdcchCfg() failed");
525          return RFAILED;
526       }
527    }
528
529    schInitDlBwp->pdschCfgPres = macInitDlBwp.pdschPresent;
530    if(schInitDlBwp->pdschCfgPres)
531    {
532       if(fillInitDlBwpPdschCfg(macInitDlBwp.pdschCfg,&schInitDlBwp->pdschCfg) != ROK)
533       {
534          DU_LOG("\nMAC : fillInitDlBwpPdschCfg() failed");
535          return RFAILED;
536       }
537    }
538    return ROK;
539 }
540
541 /*******************************************************************
542  *
543  * @brief Fills Sp Cell config to be sent to scheduler
544  *
545  * @details
546  *
547  *    Function : fillSpCellCfg 
548  *
549  *    Functionality: Fills Sp Cell config to be sent to scheduler
550  *
551  * @params[in] macSpCellCfg : SP cell cfg at MAC
552  *             schSpCellCfg : SP cell cfg to be filled
553  * @return ROK     - success
554  *         RFAILED - failure
555  *
556  * ****************************************************************/
557 uint8_t fillSpCellCfg(SpCellCfg macSpCellCfg, SchSpCellCfg *schSpCellCfg)
558 {
559    uint8_t   idx;
560    SchServCellCfgInfo   *servCellCfg;
561
562    schSpCellCfg->servCellIdx = macSpCellCfg.servCellIdx;
563    servCellCfg = &schSpCellCfg->servCellCfg;
564
565    /* Fill initial DL BWP */
566    if(fillInitialDlBwp(macSpCellCfg.servCellCfg.initDlBwp, \
567             &servCellCfg->initDlBwp) != ROK )
568    {
569       DU_LOG("\nMAC : fillInitialDlBwp() failed");
570       return RFAILED;
571    }
572
573    servCellCfg->numDlBwpToAdd = macSpCellCfg.servCellCfg.numDlBwpToAdd;
574    if(servCellCfg->numDlBwpToAdd > MAX_NUM_BWP)
575    {
576       DU_LOG("\nMAC : Number of DL BWP to ADD/MOD [%d] exceeds max limit [%d]",\
577             servCellCfg->numDlBwpToAdd, MAX_NUM_BWP);
578       return RFAILED;
579    }
580    for(idx = 0; idx < servCellCfg->numDlBwpToAdd; idx++)
581    {
582       /* TODO : As of now numDlBwpToAdd = 0 */
583    }
584
585    servCellCfg->firstActvDlBwpId =  macSpCellCfg.servCellCfg.firstActvDlBwpId;
586    servCellCfg->defaultDlBwpId = macSpCellCfg.servCellCfg.defaultDlBwpId;
587    servCellCfg->bwpInactivityTmr = NULL;
588    if(macSpCellCfg.servCellCfg.bwpInactivityTmr)
589    {
590       /* TODO : This is an optional parameter, not filled currently */
591    }
592
593    /* Fill PDSCH serving cell config */
594    if(fillPdschServCellCfg(macSpCellCfg.servCellCfg.pdschServCellCfg, \
595             &servCellCfg->pdschServCellCfg) != ROK)
596    {
597       DU_LOG("\nMAC : fillPdschServCellCfg() failed");
598       return RFAILED;
599    }
600
601    /* Fill Initail UL BWP */
602    if(fillInitialUlBwp(macSpCellCfg.servCellCfg.initUlBwp, \
603             &servCellCfg->initUlBwp) != ROK)
604    {
605       DU_LOG("\nMAC : fillInitialUlBwp() failed");
606       return RFAILED;
607    }
608
609    servCellCfg->numUlBwpToAdd = macSpCellCfg.servCellCfg.numUlBwpToAdd;
610    if(servCellCfg->numUlBwpToAdd > MAX_NUM_BWP)
611    {
612       DU_LOG("\nMAC : Number of UL BWP to ADD/MOD [%d] exceeds max limit [%d]",\
613             servCellCfg->numUlBwpToAdd, MAX_NUM_BWP);
614       return RFAILED;
615    }
616    for(idx = 0; idx < servCellCfg->numUlBwpToAdd; idx++)
617    {
618       /* TODO : As of now numDlBwpToAdd = 0 */
619    }
620    servCellCfg->firstActvUlBwpId =  macSpCellCfg.servCellCfg.firstActvUlBwpId;
621
622    return ROK;
623 }
624
625
626 /*******************************************************************
627  *
628  * @brief Fill logical channel configuration
629  *
630  * @details
631  *
632  *    Function : fillLogicalChannelCfg
633  *
634  *    Functionality: Fill logical channel configuration
635  *
636  * @params[in] macLcCfg : Logical channel Cfg at MAC
637  *             schLcCfg : LC cfg to fill at scheduler
638  * @return ROK     - success
639  *         RFAILED - failure
640  *
641  * ****************************************************************/
642 uint8_t fillLogicalChannelCfg(LcCfg macLcCfg, SchLcCfg *schLcCfg)
643 {
644    schLcCfg->lcId = macLcCfg.lcId;
645    schLcCfg->dlLcCfg.lcp = macLcCfg.dlLcCfg.lcp;
646
647    schLcCfg->drbQos = NULL;
648    if(macLcCfg.drbQos)
649    {
650       /* TODO : Optional Parameter */
651    } 
652
653    schLcCfg->snssai = NULL;
654    if(macLcCfg.snssai)
655    {
656       /* TODO : Optional Parameter */
657    }
658
659    return ROK;
660 }
661
662 /*******************************************************************
663  *
664  * @brief Fills and sends UE configuration to Scheduler
665  *
666  * @details
667  *
668  *    Function : sendAddUeCreateReqToSch
669  *
670  *    Functionality: Fills and sends UE configuration to Scheduler
671  *
672  * @params[in] Ue configuration from DU APP
673  * @return ROK     - success
674  *         RFAILED - failure
675  *
676  * ****************************************************************/
677 uint8_t sendAddUeCreateReqToSch(MacUeCfg *ueCfg)
678 {
679    Pst pst;
680    uint8_t    idx;
681    SchUeCfg   schUeCfg;
682
683    schUeCfg.cellId = ueCfg->cellId;
684    schUeCfg.crnti = ueCfg->crnti;
685
686    /* Copy MAC cell group config */
687    memset(&schUeCfg.macCellGrpCfg, 0, sizeof(SchMacCellGrpCfg));
688    if(fillMacCellGroupCfg(ueCfg->macCellGrpCfg, &schUeCfg.macCellGrpCfg) != ROK)
689    {
690       DU_LOG("\nMAC : fillMacCellGroupCfg() failed");
691       return RFAILED;
692    }
693
694    /* Copy Physical cell group config */
695    memset(&schUeCfg.phyCellGrpCfg, 0,sizeof(SchPhyCellGrpCfg));
696    if(fillPhyCellGroupCfg(ueCfg->phyCellGrpCfg, &schUeCfg.phyCellGrpCfg) != ROK)
697    {
698       DU_LOG("\nMAC : fillPhyCellGroupCfg() failed");
699       return RFAILED;
700    }
701
702    /* Copy sp cell config */
703    memset(&schUeCfg.spCellCfg, 0, sizeof(SchSpCellCfg));
704    if(fillSpCellCfg(ueCfg->spCellCfg, &schUeCfg.spCellCfg) != ROK)
705    {
706       DU_LOG("\nMAC : fillSpCellCfg() failed");
707       return RFAILED;
708    }
709
710    schUeCfg.aggrMaxBitRate = NULL;
711    if(ueCfg->maxAggrBitRate != NULL)
712    {
713
714       MAC_ALLOC(schUeCfg.aggrMaxBitRate, sizeof(SchAggrMaxBitRate));
715       if(!schUeCfg.aggrMaxBitRate)
716       {
717          DU_LOG("\nMAC : Memory allocation failed in sendAddUeCreateReqToSch");
718          return RFAILED;
719       }
720       schUeCfg.aggrMaxBitRate->ulBitRate = ueCfg->maxAggrBitRate->ulBits;
721       schUeCfg.aggrMaxBitRate->dlBitRate = ueCfg->maxAggrBitRate->dlBits;
722    }
723
724    schUeCfg.numLc = ueCfg->numLcs;
725    if(schUeCfg.numLc > MAX_NUM_LC)
726    {
727       DU_LOG("\nMAC : Number of Logical channels %d exceeds max limit %d",\
728             schUeCfg.numLc, MAX_NUM_LC);
729    }  
730    for(idx = 0; idx < schUeCfg.numLc; idx++)
731    {
732       if(fillLogicalChannelCfg(ueCfg->lcCfgList[idx], &schUeCfg.lcCfgList[idx]) != ROK)
733       {
734          DU_LOG("\nMAC : fillLogicalChannelCfg() failed");
735          return RFAILED;
736       }
737    }
738
739    /* Fill event and send UE create request to SCH */
740    FILL_PST_MAC_TO_SCH(pst, EVENT_UE_CONFIG_REQ_TO_SCH);
741    return(*macSchUeCreateReqOpts[pst.selector])(&pst, &schUeCfg);
742 }
743
744 /*******************************************************************
745  *
746  * @brief Creates UE Cb and fills ueCfg
747  *
748  * @details
749  *
750  *    Function : createUeCb
751  *
752  *    Functionality: Creates UE Cb and fills ueCfg
753  *
754  * @params[in] MAC UE Configuration
755  * @return ROK     - success
756  *         RFAILED - failure
757  *
758  * ****************************************************************/
759 uint8_t createUeCb(MacUeCfg *ueCfg)
760 {
761    uint16_t  ueIdx, lcIdx, cellIdx;
762    MacUeCb   *ueCb;
763
764    GET_CELL_IDX(ueCfg->cellId, cellIdx);
765
766    /* Validate cell id */
767    if(macCb.macCell[cellIdx]->cellId != ueCfg->cellId)
768    {
769       DU_LOG("\nMAC : Cell Id %d not configured", ueCfg->cellId);
770       return RFAILED;
771    }
772
773    /* Check if max number of UE configured */
774    if(macCb.macCell[cellIdx]->numActvUe > MAX_NUM_UE)
775    {
776       DU_LOG("MAC : Max number of UE [%d] already configured", MAX_NUM_UE);
777       return RFAILED;
778    }
779
780    /* Check if UE already configured */
781    ueCb = &macCb.macCell[cellIdx]->ueCb[ueCfg->ueIdx -1];
782    if(ueCb)
783    {
784       if((ueCb->ueIdx == ueCfg->ueIdx) && (ueCb->crnti == ueCfg->crnti) &&\
785             (ueCb->state == UE_STATE_ACTIVE))
786       {
787          DU_LOG("\n MAC : CRNTI %d already configured ", ueCfg->crnti);
788          return ROKDUP;
789       }
790    }
791
792    /* Fill received Ue Configuration in UeCb */
793    memset(ueCb, 0, sizeof(MacUeCb));
794
795    ueCb->crnti = ueCfg->crnti;
796    ueCb->cellCb = macCb.macCell[cellIdx];
797    ueCb->dlInfo.dlHarqEnt.numHarqProcs = \
798       ueCfg->spCellCfg.servCellCfg.pdschServCellCfg.numHarqProcForPdsch; 
799    ueCb->state = UE_STATE_ACTIVE;
800
801    /* Fill BSR info */
802    switch(ueCfg->macCellGrpCfg.bsrTmrCfg.periodicTimer)
803    {
804       case 0:
805          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_1MS;
806          break;
807       case 1:
808          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_5MS;
809          break;
810       case 2:
811          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_10MS;
812          break;
813       case 3:
814          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_16MS;
815          break;
816       case 4:
817          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_20MS;
818          break;
819       case 5:
820          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_32MS;
821          break;
822       case 6:
823          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_40MS;
824          break;
825       case 7:
826          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_60MS;
827          break;
828       case 8:
829          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_80MS;
830          break;
831       case 9:
832          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_128MS;
833          break;
834       case 10:
835          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_160MS;
836          break;
837       case 11:
838          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_320MS;
839          break;
840       case 12:
841          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_640MS;
842          break;
843       case 13:
844          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_1280MS;
845          break;
846       case 14:
847          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_2560MS;
848          break;
849       default:
850          DU_LOG("\nMAC : Invalid BSR Periodic Timer");
851          return RFAILED;
852    }
853
854    switch(ueCfg->macCellGrpCfg.bsrTmrCfg.retxTimer)
855    {   
856       case 0:
857          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_10MS;
858          break;
859       case 1:
860          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_20MS;
861          break;
862       case 2:
863          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_40MS;
864          break;
865       case 3:
866          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_80MS;
867          break;
868       case 4:
869          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_160MS;
870          break;
871       case 5:
872          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_320MS;
873          break;
874       case 6:
875          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_640MS;
876          break;
877       case 7:
878          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_1280MS;
879          break;
880       case 8:
881          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_2560MS;
882          break;
883       case 9:
884          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_5120MS;
885          break;
886       case 10:
887          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_10240MS;
888          break;
889       default:
890          DU_LOG("\nMAC : Invalid BSR retransmission timer");
891          break;
892    }
893
894    switch(ueCfg->macCellGrpCfg.bsrTmrCfg.srDelayTimer)
895    {
896       case 0:
897          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_20MS;
898          break;
899       case 1:
900          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_40MS;
901          break;
902       case 2:
903          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_64MS;
904          break;
905       case 3:
906          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_128MS;
907          break;
908       case 4:
909          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_512MS;
910          break;
911       case 5:
912          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_1024MS;
913          break;
914       case 6:
915          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_2560MS;
916          break;
917       default:
918          DU_LOG("\nMAC : Invalid SR delay timer");
919          return RFAILED;
920    }
921
922    /* Fill SRB1 info */
923    if(ueCfg->numLcs > MAX_NUM_LC)
924    {
925       DU_LOG("\nMAC : Number of LC to configure[%d] exceeds limit[%d]",\
926             ueCfg->numLcs, MAX_NUM_LC);
927       return RFAILED;
928    }
929
930    for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++)
931    {
932       ueCb->dlInfo.lcCb[ueCb->dlInfo.numDlLc].lcId = ueCfg->lcCfgList[lcIdx].lcId;
933       ueCb->dlInfo.lcCb[ueCb->dlInfo.numDlLc].lcState = MAC_LC_STATE_ACTIVE;
934       ueCb->dlInfo.numDlLc++;
935    }
936
937    /* Copy RA Cb */
938    for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
939    {
940       if(macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti == ueCb->crnti)
941       {
942          ueCb->raCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx];
943          break;
944       }
945    }
946
947    macCb.macCell[cellIdx]->numActvUe++;
948
949    return ROK;
950 }
951
952 /*******************************************************************
953  *
954  * @brief Handles UE create requst from DU APP
955  *
956  * @details
957  *
958  *    Function : MacProcUeCreateReq
959  *
960  *    Functionality: Handles UE create requst from DU APP
961  *
962  * @params[in] 
963  * @return ROK     - success
964  *         RFAILED - failure
965  *
966  * ****************************************************************/
967 uint8_t MacProcUeCreateReq(Pst *pst, MacUeCfg *ueCfg)
968 {
969    uint8_t ret;
970
971    DU_LOG("\nMAC : UE Create Request for CRNTI[%d]", ueCfg->crnti);
972
973    if(ueCfg)
974    {
975       ret = createUeCb(ueCfg);
976       if(ret == ROK)
977       {
978          ret = sendAddUeCreateReqToSch(ueCfg);
979          if(ret != ROK)
980          {
981             DU_LOG("\nMAC : Failed to send UE Create request to scheduler");
982          }
983       }
984       else 
985       {
986          DU_LOG("\nMAC : Failed to create MAC UE Cb ");
987       }
988    }
989    else
990    {
991       DU_LOG("\nMAC : MAC UE Create request processing failed");
992       ret = RFAILED;
993    }
994    /* FREE shared memory */
995    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(MacUeCfg));
996
997    return ret;
998 }
999
1000 /*******************************************************************
1001  *
1002  * @brief Fill and Send UE create response from MAC to DU APP
1003  *
1004  * @details
1005  *
1006  *    Function : MacSendUeCreateRsp
1007  *
1008  *    Functionality: Fill and Send UE create response from MAC to DUAPP
1009  *
1010  * @params[in] MAC UE create result
1011  *             SCH UE create response
1012  * @return ROK     - success
1013  *         RFAILED - failure
1014  *
1015  * ****************************************************************/
1016 uint8_t MacSendUeCreateRsp(MacRsp result, SchUeCfgRsp *schCfgRsp)
1017 {
1018    MacUeCfgRsp   *cfgRsp;
1019    Pst        rspPst;
1020
1021    MAC_ALLOC_SHRABL_BUF(cfgRsp, sizeof(MacUeCfgRsp));
1022    if(!cfgRsp)
1023    {
1024       DU_LOG("\nMAC: Memory allocation for UE config response failed");
1025       return RFAILED;
1026    }
1027
1028    /* Filling UE Config response */
1029    memset(cfgRsp, 0, sizeof(MacUeCfgRsp));
1030    cfgRsp->cellId = schCfgRsp->cellId;
1031    cfgRsp->ueIdx = schCfgRsp->ueIdx;
1032    cfgRsp->result = result;
1033
1034    /* Fill Post structure and send UE Create response*/
1035    memset(&rspPst, 0, sizeof(Pst));
1036    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_UE_CONFIG_RSP);
1037    return MacDuUeCfgRspOpts[rspPst.selector](&rspPst, cfgRsp); 
1038 }
1039
1040
1041 /*******************************************************************
1042  *
1043  * @brief  Processes UE create response from scheduler
1044  *
1045  * @details
1046  *
1047  *    Function : MacProcSchUeCfgRsp
1048  *
1049  *    Functionality:
1050  *      Processes UE create response from scheduler
1051  *      Sends UE create response to DU APP
1052  *
1053  * @params[in] Pst : Post structure
1054  *             schCfgRsp : Scheduler UE cfg response
1055  * @return ROK     - success
1056  *         RFAILED - failure
1057  *
1058  * ****************************************************************/
1059 uint8_t MacProcSchUeCfgRsp(Pst *pst, SchUeCfgRsp *schCfgRsp)
1060 {
1061    uint8_t result = MAC_DU_APP_RSP_NOK;
1062    uint8_t ret = ROK;
1063    uint16_t cellIdx;
1064
1065    GET_CELL_IDX(schCfgRsp->cellId, cellIdx);
1066
1067    if(schCfgRsp->rsp == RSP_NOK)
1068    {
1069       DU_LOG("\nMAC : SCH UE Create Response : FAILURE [CRNTI %d]", schCfgRsp->crnti);
1070       memset(&macCb.macCell[cellIdx]->ueCb[schCfgRsp->ueIdx -1], 0, sizeof(MacUeCb));
1071       macCb.macCell[cellIdx]->numActvUe--;
1072       result = MAC_DU_APP_RSP_NOK;
1073    }
1074    else
1075    {
1076       DU_LOG("\nMAC : SCH UE Create Response : SUCCESS [CRNTI %d]", schCfgRsp->crnti);
1077       result = MAC_DU_APP_RSP_OK;
1078    }
1079    ret = MacSendUeCreateRsp(result, schCfgRsp);
1080    return ret; 
1081 }
1082
1083 /*******************************************************************
1084  *
1085  * @brief Handles UE Reconfig requst from DU APP
1086  *
1087  * @details
1088  *
1089  *    Function : MacProcUeReconfigReq
1090  *
1091  *    Functionality: Handles UE Reconfig requst from DU APP
1092  *
1093  * @params[in] 
1094  * @return ROK     - success
1095  *         RFAILED - failure
1096  *
1097  * ****************************************************************/
1098 uint8_t MacProcUeReconfigReq(Pst *pst, MacUeCfg *ueCfg)
1099 {
1100    //TODO:
1101    return ROK;
1102 }
1103
1104
1105 /**********************************************************************
1106   End of file
1107  **********************************************************************/