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