Initial commit
[o-du/l2.git] / src / 5gnrmac / rg_rom.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 /************************************************************************
20  
21      Name:     LTE-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for Entry point fucntions.
26   
27      File:     rg_rom.c
28   
29 **********************************************************************/
30
31 /** @file rg_rom.c
32 @brief APIs to handle all the primitives invoked on RGU interface.
33 */
34
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=184;
37 static int RLOG_MODULE_ID=4096;
38
39 /* header include files (.h) */
40 #include "envopt.h"        /* environment options */
41 #include "envdep.h"        /* environment dependent */
42 #include "envind.h"        /* environment independent */
43   
44 #include "gen.h"           /* general */
45 #include "ssi.h"           /* system services */
46
47 #include "cm_tkns.h"       /* Common Token Defines */
48 #include "cm_llist.h"      /* Common Link List Defines */
49 #include "cm_hash.h"       /* Common Hash List Defines */
50 #include "cm_mblk.h"       /* common memory link list library */
51 #include "cm_lte.h"        /* Common LTE */
52
53 #include "rg_env.h"        /* MAC Environment Defines */
54 #include "crg.h"           /* CRG Interface defines */
55 #include "rgu.h"           /* RGU Interface defines */
56 #include "tfu.h"           /* TFU Interface defines */
57 #include "rg_sch_inf.h"           /* RGR Interface defines */
58 #include "lrg.h"           /* LRG Interface defines */
59
60 #include "rg.h"            /* MAC defines */
61 #include "rg_err.h"        /* MAC error defines */
62
63 /* header/extern include files (.x) */
64 #include "gen.x"           /* general */
65 #include "ssi.x"           /* system services */
66 #include "cm5.x"           /* Timer */
67 #include "cm_tkns.x"       /* Common Token Definitions */
68 #include "cm_llist.x"      /* Common Link List Definitions */
69 #include "cm_lib.x"        /* Common Library Definitions */
70 #include "cm_hash.x"       /* Common Hash List Definitions */
71 #include "cm_mblk.x"       /* common memory link list library */
72 #include "cm_lte.x"        /* Common LTE */
73
74 #include "crg.x"           /* CRG Interface includes */
75 #include "rgu.x"           /* RGU Interface includes */
76 #include "tfu.x"           /* TFU Interface includes */
77 #include "rg_sch_inf.x"    /* SCH Interface includes */
78 #include "rg_prg.x"        /* PRG Interface includes */
79 #include "lrg.x"           /* LRG Interface includes */
80
81 #include "rg.x"            /* MAC includes */
82
83 /* local defines */
84 #define RG_NON_MIMO_IDX 0
85
86 /* local typedefs */
87  
88 S16 RgMacSchBrdcmDedBoUpdtReq ARGS((Inst inst, CmLteCellId cellId, CmLteRnti rnti, CmLteLcId lcId, S32 bo ));
89 PRIVATE S16 rgROMHndlCcchDatReq     ARGS((RgCellCb *cell,
90                                     RgRguCmnDatReq *datReq, RgErrInfo *err));
91 PRIVATE S16 rgROMHndlBcchPcchDatReq ARGS((RgCellCb *cell,
92                                     RgRguCmnDatReq *datReq, RgErrInfo *err));
93 PRIVATE S16 rgROMHndlCcchStaRsp     ARGS((RgCellCb *cell, 
94                                     RgRguCmnStaRsp *staRsp, RgErrInfo *err));
95 PRIVATE S16 rgROMHndlBcchPcchStaRsp ARGS((RgCellCb *cell, 
96                                     RgRguCmnStaRsp *staRsp, RgErrInfo *err));
97
98 /* ADD Changes for Downlink UE Timing Optimization */
99 #ifdef LTEMAC_DLUE_TMGOPTMZ
100 PRIVATE S16 rgROMUpdDlSfRemDataCnt ARGS((RgCellCb  *cellCb,
101                                     RgDlSf    *dlSf));
102 PUBLIC S16 rgTOMUtlProcDlSf ARGS(( RgDlSf     *dlSf,
103                                    RgCellCb   *cellCb,
104                                    RgErrInfo  *err));
105 #endif
106
107 /* forward references */
108
109 /**
110  * @brief Handler for dedicated DatReq received on RGU for an UE.
111  *
112  * @details
113  *
114  *     Function : rgROMDedDatReq
115  *     
116  *     This function shall
117  *      -# store the BO reported for the given logical channels.
118  *      -# invoke DL HARQ for further processing.
119  *     
120  *           
121  *  @param[in]  Inst        inst
122  *  @param[in]  RgRguDedDatReq *datReq 
123  *  @return  S16
124  *      -# ROK 
125  *      -# RFAILED 
126  **/
127 #ifdef ANSI
128 PUBLIC S16 rgROMDedDatReq
129 (
130 Inst      inst,
131 RgRguDedDatReq *datReq
132 )
133 #else
134 PUBLIC S16 rgROMDedDatReq(inst,datReq)
135 Inst      inst;
136 RgRguDedDatReq *datReq;
137 #endif
138 {
139    RgCellCb     *cell;
140    RgUeCb       *ue;
141    U8           idx1,idx2;
142    RgDlHqProcCb *hqProc;
143    U8           hqPId;
144    RgErrInfo    err;
145    Pst          schPst;
146    RgInfDedBoRpt boRpt;
147    CmLteTimingInfo timingInfo;
148    RgDlSf       *sf;
149 #if (ERRCLASS & ERRCLS_DEBUG)
150    RgUstaDgn   dgn;      /* Alarm diagnostics structure */
151 #endif
152 /* ADD Changes for Downlink UE Timing Optimization */
153 #ifdef LTEMAC_DLUE_TMGOPTMZ
154    S16 ret;
155 #endif
156    U32 idx;
157    //U8  datReqFailCnt = 0;
158
159    TRC2(rgROMDedDatReq)
160
161
162    if (((cell = rgCb[inst].cell) == NULLP) 
163        || (cell->cellId != datReq->cellId))
164    {
165 #if (ERRCLASS & ERRCLS_INT_PAR)
166       /* Handle Cell fetch failure */
167       RGLOGERROR(inst,ERRCLS_INT_PAR,ERG001,(ErrVal)datReq->cellId,
168             "rgROMDedDatReq(): Invalid cell Id");
169 #endif
170       err.errType = RGERR_ROM_DEDDATREQ;
171       err.errCause = RGERR_ROM_INV_CELL_ID;
172       if(cell != NULLP)
173       {
174          /* Update stats */
175          rgUpdtRguDedSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP, datReq);
176       }
177       RETVALUE(RFAILED);
178    }
179
180 /* Add loop here to scan for all UEs in the consolidated DDatReq*/
181    for(idx = 0; idx < datReq->nmbOfUeGrantPerTti; idx++)
182    {
183
184       timingInfo.subframe = (U8)((datReq->datReq[idx].transId >> 8) & 0XFF);
185       timingInfo.sfn = (U16)((datReq->datReq[idx].transId >> 16) & 0xFFFF);
186       sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)];
187
188       if( (sf->txDone == TRUE) ||
189             (!RG_TIMEINFO_SAME(sf->schdTime,timingInfo)))
190       {
191 #if (ERRCLASS & ERRCLS_DEBUG)
192          /* Transmission is already done for this subframe. This is a delayed
193           * datReq. So discard */
194          rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
195          rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
196                LRG_CAUSE_DELAYED_DATREQ, &dgn);
197 #endif
198          err.errType = RGERR_ROM_DEDDATREQ;
199          err.errCause = RGERR_ROM_DELAYED_DATREQ;
200          /* Update stats */
201          rgUpdtRguDedSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP, datReq);
202 #ifdef CA_DBG
203          {
204             EXTERN U32 dbgDelayedDatReqInMac;
205             dbgDelayedDatReqInMac++;
206          }
207 #endif /* CA_DBG */         
208 #ifndef L2_OPTMZ
209          RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]);
210 #endif
211          continue;
212         // RETVALUE(RFAILED);
213       }
214
215       if ((ue = rgDBMGetUeCb(cell, datReq->datReq[idx].rnti)) == NULLP)
216       {
217 #if (ERRCLASS & ERRCLS_INT_PAR)
218             /* Handle Ue fetch failure */
219             RGLOGERROR(inst,ERRCLS_INT_PAR,ERG002,(ErrVal)datReq->datReq[idx].rnti,
220                   "rgROMDedDatReq(): Invalid ue Id");
221 #endif
222             err.errType = RGERR_ROM_DEDDATREQ;
223             err.errCause = RGERR_ROM_INV_UE_ID;
224             /* Update stats */
225             rgUpdtRguDedSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP, datReq);
226             /* ADD Changes for Downlink UE Timing Optimization */
227 #ifdef LTEMAC_DLUE_TMGOPTMZ
228             /* Trying to send the prev successful PDU's 
229              * if present */
230             ret = rgROMUpdDlSfRemDataCnt(cell, sf);
231             if(ret == RFAILED)
232             {
233                RLOG0(L_INFO, "Dropping due to no ue \n");
234 #ifndef L2_OPTMZ
235                RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]);
236 #endif
237                /* Return from here as above functions found more datReq than expected*/
238               /* RETVALUE(ret); */
239             }
240 #endif
241             /* Conitnue for next UE */
242             continue;
243       }
244
245       hqPId = (U8)(datReq->datReq[idx].transId);
246       hqPId = hqPId >> 2;
247       /* get harq process and invoke DHM */
248       rgDHMGetHqProcFrmId(ue, hqPId, &hqProc);
249
250       if (rgDHMHndlDedDatReq(inst,hqProc, &datReq->datReq[idx], sf, &err) == RFAILED)
251       {
252          RLOG_ARG1(L_ERROR,DBG_CELLID,datReq->cellId,
253                    "Handling of Data request in DHM failedi RNTI:%d",
254                     datReq->datReq[idx].rnti);
255          err.errType = RGERR_ROM_DEDDATREQ;
256          /* errcause shall be filled in appropriately by DHM */
257          /* Update stats */
258          rgUpdtRguDedSts(inst,ue->rguDlSap,RG_RGU_SDU_DROP, datReq);
259          /* ADD Changes for Downlink UE Timing Optimization */
260 #ifdef LTEMAC_DLUE_TMGOPTMZ
261          /* Trying to send the prev successful PDU's 
262           * if present */
263          ret = rgROMUpdDlSfRemDataCnt(cell, sf);
264          if(ret == RFAILED)
265          {
266          RLOG0(L_INFO, "Dropping due to no failure of remCnt update");
267 #ifndef L2_OPTMZ
268             RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]);
269 #endif
270             /* Return from here as above functions found more datReq than expected*/
271             //RETVALUE(ret);
272          }
273 #endif
274          continue;
275       }
276
277       /* Merging the updation of statistics of SDUs with for loop below */ 
278
279       rgGetPstToInst(&schPst,inst, cell->schInstMap.schInst);
280       schPst.event = 0;
281       boRpt.cellSapId  = cell->schInstMap.cellSapId;
282       boRpt.cellId  = datReq->cellId;
283
284       boRpt.rnti    = datReq->datReq[idx].rnti; 
285
286
287       /* Fill the DStaRsp struct and send it to scheduler */
288       for (idx1 = 0; idx1 < datReq->datReq[idx].nmbOfTbs; idx1++)
289       {
290          for(idx2 = 0; idx2 < datReq->datReq[idx].datReqTb[idx1].nmbLch; idx2++)
291          {
292             /* Updating dedicated SDUs received statistics without 
293                additional function above for optimization */
294             ue->rguDlSap->sapSts.numPduRcvd +=
295                datReq->datReq[idx].datReqTb[idx1].lchData[idx2].pdu.numPdu;
296
297             boRpt.lcId    = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].lcId; 
298             boRpt.bo      = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.bo;
299             boRpt.oldestSduArrTime 
300                = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.oldestSduArrTime;
301             boRpt.staPduBo = datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.staPduBo;
302             
303             boRpt.setMaxUlPrio= datReq->datReq[idx].datReqTb[idx1].lchData[idx2].setMaxUlPrio;
304 #ifdef CCPU_OPT
305             boRpt.setMaxDlPrio= datReq->datReq[idx].datReqTb[idx1].lchData[idx2].boReport.staPduPrsnt;
306 #endif
307             RgMacSchDedBoUpdt(&schPst, &boRpt);
308          }
309       }
310
311       /* ADD Changes for Downlink UE Timing Optimization */
312 #ifdef LTEMAC_DLUE_TMGOPTMZ
313 //       sf->remDatReqCnt -= datReqFailCnt;
314       /*Presently this function is not returning RFAILED, thus not checking
315         for failure condition.*/
316       ret = rgROMUpdDlSfRemDataCnt(cell, sf);
317       if(ret == RFAILED)
318       {
319          RLOG0(L_INFO, "\n Dropping due to no failure of remCnt update(1) \n");
320 #ifndef L2_OPTMZ
321          RG_DROP_RGUDDATREQ_MBUF(datReq->datReq[idx]);
322 #endif
323          /* Return from here as above functions found more datReq than expected*/
324         // RETVALUE(ret);
325       }
326 #endif
327    } /* for loop for num of Ue per TTI*/
328
329    /* Data send successfully to PHY. lets retuns ROK*/
330    RETVALUE(ROK);
331 }  /* rgROMDedDatReq */
332
333
334 /**
335  * @brief Handler for DatReq received on RGU for a common logical channel.
336  *
337  * @details
338  *
339  *     Function : rgROMCmnDatReq
340  *     
341  *     This function shall invoke rgROMHndlCcchDatReq() if datReq is on CCCH
342  *     If not, it shall invoke rgROMHndlBcchPcchDatReq().
343  *     
344  *           
345  *  @param[in]  Inst        inst
346  *  @param[in]  RgRguCmnDatReq *datReq 
347  *  @return  S16
348  *      -# ROK 
349  *      -# RFAILED 
350  **/
351 #ifdef ANSI
352 PUBLIC S16 rgROMCmnDatReq
353 (
354 Inst            inst,
355 RgRguCmnDatReq *datReq
356 )
357 #else
358 PUBLIC S16 rgROMCmnDatReq(inst,datReq)
359 Inst            inst;
360 RgRguCmnDatReq *datReq;
361 #endif
362 {
363    RgCellCb    *cell;
364    RgErrInfo   err;
365    S16         ret;
366 /* ADD Changes for Downlink UE Timing Optimization */
367 #ifdef LTEMAC_DLUE_TMGOPTMZ
368    CmLteTimingInfo timingInfo;
369    RgDlSf   *sf;
370 #endif
371
372    TRC2(rgROMCmnDatReq)
373
374    ret = ROK;
375    err.errType = RGERR_ROM_CMNDATREQ;
376    if(((cell = rgCb[inst].cell) == NULLP)
377       ||(cell->cellId != datReq->cellId))
378    {
379 #if (ERRCLASS & ERRCLS_INT_PAR)
380       /* Handle Cell fetch failure */
381       RGLOGERROR(inst,ERRCLS_INT_PAR,ERG003,(ErrVal)datReq->cellId,
382                             "rgROMCmnDatReq(): Invalid cell Id");
383 #endif
384       err.errCause = RGERR_ROM_INV_CELL_ID;
385       /* Update stats */
386       if(cell != NULLP)
387       {
388          rgUpdtRguCmnSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP);
389       }
390       RETVALUE(RFAILED);
391    }
392
393    if (datReq->lcId == cell->dlCcchId)
394    {
395       ret = rgROMHndlCcchDatReq(cell, datReq, &err);
396
397       /*Get the timing Info*/
398       /* ADD Changes for Downlink UE Timing Optimization */
399 #ifdef LTEMAC_DLUE_TMGOPTMZ
400       timingInfo.subframe = (U8)((datReq->transId >> 8) & 0XFF);
401       timingInfo.sfn = (U16)((datReq->transId >> 16) & 0xFFFF);
402 #endif
403    } 
404    else
405    {
406       ret = rgROMHndlBcchPcchDatReq(cell, datReq, &err);
407
408       /*Get the timing Info*/
409       /* ADD Changes for Downlink UE Timing Optimization */
410 #ifdef LTEMAC_DLUE_TMGOPTMZ
411       timingInfo.subframe = (U8)(datReq->transId & 0XFF);
412       timingInfo.sfn = (U16)((datReq->transId >> 8) & 0xFFFF);
413 #endif
414    }
415
416    /* Update stats */
417    if (ret == RFAILED)
418    {
419       rgUpdtRguCmnSts(inst,cell->rguDlSap,RG_RGU_SDU_DROP);
420    }
421    else
422    {
423       /* Update stats with number of SDUs received */
424       rgUpdtRguCmnSts(inst,cell->rguDlSap,RG_RGU_SDU_RCVD);
425    }
426
427    /* ADD Changes for Downlink UE Timing Optimization */
428 #ifdef LTEMAC_DLUE_TMGOPTMZ
429    RG_ARRAY_BOUND_CHECK(0, cell->subFrms, (timingInfo.subframe % RG_NUM_SUB_FRAMES));
430    sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)];
431
432    ret = rgROMUpdDlSfRemDataCnt(cell, sf);
433    /*Added check for RFAILED as above function can return RFAILED*/
434 #endif
435
436    RETVALUE(ret);
437 }  /* rgROMCmnDatReq */
438
439 /**
440  * @brief Handler for DatReq received on RGU for CCCH.
441  *
442  * @details
443  *
444  *     Function : rgROMHndlCcchDatReq
445  *     
446  *     This function shall fetch the raCb with the given rnti and indicate msg4
447  *     arrival to RAM.
448  *     
449  *           
450  *  @param[in]  RgCellCb       *cell
451  *  @param[in]  RgRguCmnDatReq *datReq 
452  *  @param[out] RgErrInfo      *err
453  *  @return  S16
454  *      -# ROK 
455  *      -# RFAILED 
456  **/
457 #ifdef ANSI
458 PRIVATE S16 rgROMHndlCcchDatReq
459 (
460 RgCellCb       *cell,
461 RgRguCmnDatReq *datReq,
462 RgErrInfo      *err
463 )
464 #else
465 PRIVATE S16 rgROMHndlCcchDatReq(cell, datReq, err)
466 RgCellCb       *cell;
467 RgRguCmnDatReq *datReq;
468 RgErrInfo      *err;
469 #endif
470 {
471    Inst     inst = cell->macInst - RG_INST_START;
472    RgUeCb   *ue;
473    U8       hqPId;
474    RgDlHqProcCb *hqProc;
475    CmLteTimingInfo timingInfo;
476    RgDlSf   *sf;
477 #if (ERRCLASS & ERRCLS_DEBUG)
478    RgUstaDgn   dgn;      /* Alarm diagnostics structure */
479 #endif
480
481    TRC2(rgROMHndlCcchDatReq);
482
483
484    err->errType = RGERR_ROM_CMNDATREQ;
485
486    if ((ue = rgDBMGetUeCb(cell, datReq->u.rnti)) == NULLP)
487    {
488       if ((ue = rgDBMGetUeCbFromRachLst(cell, datReq->u.rnti)) == NULLP)
489       {
490    #if (ERRCLASS & ERRCLS_INT_PAR)
491          /* Handle Ue fetch failure */
492          RGLOGERROR(inst,ERRCLS_INT_PAR,ERG004,(ErrVal)datReq->u.rnti,
493                               "rgROMHndlCcchDatReq(): Invalid ue Id");
494    #endif
495          err->errCause = RGERR_ROM_INV_UE_ID;
496          RETVALUE(RFAILED);
497       }
498    }
499
500    timingInfo.subframe = (U8)((datReq->transId >> 8) & 0XFF);
501    timingInfo.sfn = (U16)((datReq->transId >> 16) & 0xFFFF);
502    sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)];
503
504    if( (sf->txDone == TRUE) ||
505        (!RG_TIMEINFO_SAME(sf->schdTime,timingInfo)))
506    {
507 #if (ERRCLASS & ERRCLS_DEBUG)
508       /* Transmission is already done for this subframe. This is a delayed
509        * datReq. So discard */
510       rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
511       rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
512                               LRG_CAUSE_DELAYED_DATREQ, &dgn);
513 #endif
514       err->errCause = RGERR_ROM_DELAYED_DATREQ;
515       RETVALUE(RFAILED);
516    }
517
518    hqPId = (U8)(datReq->transId);
519    hqPId = hqPId >> 2;
520
521    /* get harq process and invoke DHM */
522    rgDHMGetHqProcFrmId(ue, hqPId, &hqProc);
523  
524    /* Changed for CR timer implementation*/
525    /* invoke DHM to process CCCH data */
526    if (rgDHMHndlCmnDatReq(inst,hqProc, datReq, err) == RFAILED)
527    {
528       RLOG_ARG2(L_ERROR,DBG_CELLID,cell->cellId,
529             "Handling of Data request in DHM failed RNTI:%d LCID:%d",
530             datReq->u.rnti,datReq->lcId);
531       /* Release First TB */
532       rgDHMRlsHqProcTB(cell, hqProc, 1);
533       /* err shall be filled in appropriately by DHM */
534       RETVALUE(RFAILED);
535    }
536  
537    RETVALUE(ROK); 
538 } /* rgROMHndlCcchDatReq */
539
540
541 /**
542  * @brief Handler for DatReq received on RGU for BCCH or PCCH.
543  *
544  * @details
545  *
546  *     Function : rgROMHndlBcchPcchDatReq
547  *     
548  *     This function shall store the buffer and time to transmit in lcCb.
549  *     
550  *           
551  *  @param[in]  RgCellCb       *cell
552  *  @param[in]  RgRguCmnDatReq *datReq 
553  *  @param[out] RgErrInfo      *err
554  *  @return  S16
555  *      -# ROK 
556  *      -# RFAILED 
557  **/
558 #ifdef ANSI
559 PRIVATE S16 rgROMHndlBcchPcchDatReq
560 (
561 RgCellCb       *cell,
562 RgRguCmnDatReq *datReq,
563 RgErrInfo      *err
564 )
565 #else
566 PRIVATE S16 rgROMHndlBcchPcchDatReq(cell, datReq, err)
567 RgCellCb       *cell;
568 RgRguCmnDatReq *datReq;
569 RgErrInfo      *err;
570 #endif
571 {
572    Inst            inst = cell->macInst - RG_INST_START;
573    RgPcchLcCb      *pcch;
574    /* Modified for SI Enhancement*/
575 #ifndef RGR_SI_SCH
576    RgBcchBchLcCb   *bch;
577    RgBcchDlschLcCb *bcch;
578 #endif/*RGR_SI_SCH*/
579    RgDlSf          *sf;
580    CmLteTimingInfo timingInfo;
581 #if (ERRCLASS & ERRCLS_DEBUG)
582    RgUstaDgn   dgn;      /* Alarm diagnostics structure */
583 #endif
584
585    TRC2(rgROMHndlBcchPcchDatReq);
586
587
588    timingInfo.subframe = (U8)(datReq->transId & 0XFF);
589    timingInfo.sfn = (U16)((datReq->transId >> 8) & 0xFFFF);
590    sf = &cell->subFrms[(timingInfo.subframe % RG_NUM_SUB_FRAMES)];
591
592    if( (sf->txDone == TRUE) ||
593        (!RG_TIMEINFO_SAME(sf->schdTime,timingInfo)))
594    {
595 #if (ERRCLASS & ERRCLS_DEBUG)
596       /* Transmission is already done for this subframe. This is a delayed
597        * datReq. So discard */
598       rgFillDgnParams(inst,&dgn, LRG_USTA_DGNVAL_MEM);
599       rgLMMStaInd(inst,LCM_CATEGORY_PROTOCOL, LCM_EVENT_UI_INV_EVT,
600                               LRG_CAUSE_DELAYED_DATREQ, &dgn);
601 #endif
602       err->errCause = RGERR_ROM_DELAYED_DATREQ;
603       RETVALUE(RFAILED);
604    }
605
606 #ifndef RGR_SI_SCH
607    bcch = rgDBMGetBcchOnDlsch(cell,datReq->lcId);
608    if (bcch )
609    {
610       /* Store BCCH-DLSCH data received in Scheduled subframe */
611       sf->bcch.tb = datReq->pdu;
612
613       SCpyMsgMsg(datReq->pdu, RG_GET_MEM_REGION(rgCb[inst]),
614                RG_GET_MEM_POOL(rgCb[inst]), &bcch->tb);
615
616       RETVALUE(ROK);
617    }
618
619    bch = rgDBMGetBcchOnBch(cell);
620    if ((bch) && (bch->lcId == datReq->lcId))
621    {
622       /* Store BCH data received in Scheduled subframe */
623       sf->bch.tb = datReq->pdu;
624       RETVALUE(ROK);
625    }
626 #endif/*RGR_SI_SCH*/
627
628    pcch = rgDBMGetPcch(cell);
629    if ((pcch) && (pcch->lcId == datReq->lcId))
630    {
631       /* Store PCCH-DLSCH data received in Scheduled subframe */
632       sf->pcch.tb = datReq->pdu;
633       RETVALUE(ROK);
634    }
635
636    /* Handle lcCb fetch failure */
637    RGLOGERROR(inst,ERRCLS_INT_PAR,ERG005,(ErrVal)datReq->lcId,
638                   "rgROMHndlBcchPcchDatReq(): Invalid Lc Id");
639    err->errCause = RGERR_ROM_INV_LC_ID;
640
641    RETVALUE(RFAILED);
642 } /* rgROMHndlBcchPcchDatReq */
643
644 /**
645  * @brief Handler for StaRsp received on RGU for a dedicated logical channel.
646  *
647  * @details
648  *
649  *     Function : rgROMDedStaRsp
650  *     
651  *     This fucntion shall store the BO reported for the given logical
652  *     channel.
653  *     
654  *           
655  *  @param[in]  Inst        inst
656  *  @param[in]  RgRguDedStaRsp *staRsp 
657  *  @return  S16
658  *      -# ROK 
659  *      -# RFAILED 
660  **/
661 #ifdef ANSI
662 PUBLIC S16 rgROMDedStaRsp
663 (
664 Inst           inst,
665 RgRguDedStaRsp *staRsp
666 )
667 #else
668 PUBLIC S16 rgROMDedStaRsp(inst,staRsp)
669 Inst           inst;
670 RgRguDedStaRsp *staRsp;
671 #endif
672 {
673    RgCellCb   *cell;
674
675    /* Moving the error variables and assignments to available scope */
676
677    TRC2(rgROMDedStaRsp)
678
679    /* Avoiding memset, as the variables of this are getting 
680       initialized */
681
682
683    if(((cell = rgCb[inst].cell) != NULLP)
684       && (cell->cellId == staRsp->cellId))
685    {
686             RgInfDedBoRpt boRpt;
687             Pst        schPst;
688             boRpt.cellSapId  = cell->schInstMap.cellSapId;
689             boRpt.cellId  = staRsp->cellId;
690             boRpt.rnti    = staRsp->rnti; 
691             boRpt.lcId    = staRsp->lcId; 
692             boRpt.bo      = staRsp->boReport.bo;
693             boRpt.oldestSduArrTime = staRsp->boReport.oldestSduArrTime;
694             boRpt.staPduBo = staRsp->boReport.staPduBo;
695                         boRpt.oldestSduArrTime = staRsp->boReport.oldestSduArrTime;
696             rgGetPstToInst(&schPst,inst, cell->schInstMap.schInst);
697             schPst.event = 0;
698             RgMacSchDedBoUpdt(&schPst, &boRpt);
699             RETVALUE(ROK);
700    }
701    RLOG_ARG2(L_ERROR,DBG_CELLID,staRsp->cellId,"Invalid cell for CRNTI:%d LCID:%d ",
702              staRsp->rnti,staRsp->lcId);
703
704    RETVALUE(RFAILED);
705 }  /* rgROMDedStaRsp */
706
707 S16 RgMacSchBrdcmDedBoUpdtReq(
708 Inst inst,
709 CmLteCellId cellId,
710 CmLteRnti rnti, 
711 CmLteLcId lcId, 
712 S32 bo 
713 )
714 {
715   RgInfDedBoRpt  boRpt;
716   RgCellCb   *cell;
717   //if ((cell = rgDBMGetCellCb(cellId)) != NULLP)
718   if (((cell = rgCb[inst].cell) != NULLP) &&
719         (cell->cellId == cellId))
720   {
721      Pst        schPst;
722      boRpt.cellSapId  = cell->schInstMap.cellSapId;
723      boRpt.cellId     = cellId;
724      boRpt.rnti       = rnti; 
725      boRpt.lcId       = lcId; 
726      boRpt.bo         = bo;
727      rgGetPstToInst(&schPst,inst, cell->schInstMap.schInst);
728      schPst.event = 0;
729      RgMacSchDedBoUpdtReq (&schPst,&boRpt);
730   }
731   RETVALUE(ROK);
732 }
733 /**
734  * @brief Handler for StaRsp received on RGU for a common logical channel.
735  *
736  * @details
737  *
738  *     Function : rgROMCmnStaRsp
739  *     
740  *     This fucntion shall invoke rgROMHndlCcchStaRsp() for status response on
741  *     CCCH and shall invoke rgROMHndlBcchPcchStaRsp() for status response on
742  *     BCCH or PCCH.
743  *     
744  *           
745  *  @param[in]  Inst        inst
746  *  @param[in]  RgRguCmnStaRsp *staRsp 
747  *  @return  S16
748  *      -# ROK 
749  *      -# RFAILED 
750  **/
751 #ifdef ANSI
752 PUBLIC S16 rgROMCmnStaRsp
753 (
754 Inst            inst, 
755 RgRguCmnStaRsp *staRsp
756 )
757 #else
758 PUBLIC S16 rgROMCmnStaRsp(inst,staRsp)
759 Inst            inst;
760 RgRguCmnStaRsp *staRsp;
761 #endif
762 {
763    RgCellCb   *cell;
764    RgErrInfo  err;
765
766    TRC2(rgROMCmnStaRsp)
767
768
769    if(((cell = rgCb[inst].cell) == NULLP)
770       || (cell->cellId != staRsp->cellId))
771    {
772       /* Handle Cell fetch failure */
773       RLOG_ARG2(L_ERROR,DBG_CELLID,staRsp->cellId,
774                 "Invalid cell for CRNTI:%d LCID:%d",staRsp->u.rnti,staRsp->lcId);
775       err.errType = RGERR_ROM_CMNSTARSP;
776       err.errCause = RGERR_ROM_INV_CELL_ID;
777       RETVALUE(RFAILED);
778    }
779
780    /* handle status response on CCCH */
781    if(staRsp->lcId == cell->dlCcchId)
782    {
783       rgROMHndlCcchStaRsp(cell, staRsp, &err); 
784    }
785    else
786    {
787       rgROMHndlBcchPcchStaRsp(cell, staRsp, &err); 
788    }
789    
790    RETVALUE(ROK);
791 }  /* rgROMCmnStaRsp */
792
793 #ifdef LTE_L2_MEAS
794
795 /**
796  * @brief Handler for Request received on RGU for a UL Throughput measurement
797  * enabled logical channel.
798  *
799  * @details
800  *
801  *     Function :rgROML2MUlThrpMeasReq 
802  *     
803  *     This function shall store the L2M UL Throughput Measurement status  information 
804  *     for the given logical channel.
805  *     
806  *           
807  *  @param[in]  Inst        inst
808  *  @param[in]  RgRguL2MUlThrpMeasReq *measReq 
809  *  @return  S16
810  *      -# ROK 
811  *      -# RFAILED 
812  **/
813 #ifdef ANSI
814 PUBLIC S16 rgROML2MUlThrpMeasReq 
815 (
816 Inst                  inst,
817 RgRguL2MUlThrpMeasReq *measReq
818 )
819 #else
820 PUBLIC S16 rgROML2MUlThrpMeasReq(inst,measReq)
821 Inst                  inst;
822 RgRguL2MUlThrpMeasReq *measReq;
823 #endif
824 {
825    RgCellCb   *cell;
826    RgUeCb     *ue;
827    U8         lcgId;
828    U8         loop;
829    TRC2(rgROML2MUlThrpMeasReq)
830
831
832
833    if(((cell = rgCb[inst].cell) != NULLP)
834       &&(cell->cellId == measReq->cellId))
835    {
836       if ((ue = rgDBMGetUeCb(cell, measReq->rnti)) != NULLP)
837       {
838          for(loop=0; loop<measReq->numLcId;loop++)
839          {
840             if ((rgDBMGetUlDedLcCb(ue, measReq->lcId[loop])) != NULLP)
841             {
842                ue->ul.lcCb[measReq->lcId[loop]].measOn = measReq->enbMeas;
843                if(ue->ul.lcCb[measReq->lcId[loop]].measOn == FALSE)
844                {
845                   lcgId=ue->ul.lcCb[measReq->lcId[loop]].lcgId;
846                   ue->ul.lcgArr[lcgId].lcgBsInfo.outStndngBs = 0;
847                   ue->ul.lcgArr[lcgId].lcgBsInfo.firstDatSegRcvd = FALSE;
848                }
849             }
850          }
851          RETVALUE(ROK);
852       }
853    }
854    RLOG_ARG1(L_ERROR,DBG_CELLID,measReq->cellId,"Invalid cell CRNTI:%d",
855              measReq->rnti);
856    RETVALUE(RFAILED);
857 }  /* rgROML2MUlThrpMeasReq */
858
859 #endif
860
861 /**
862  * @brief Handler for StaRsp received on RGU for CCCH.
863  *
864  * @details
865  *
866  *     Function : rgROMHndlCcchStaRsp
867  *     
868  *     This function shall fetch the raCb with the given RNTI and ask RAM to
869  *     update BO. 
870  *     
871  *           
872  *  @param[in]  RgCellCb       *cell
873  *  @param[in]  RgRguCmnStaRsp *staRsp
874  *  @param[out] RgErrInfo      *err
875  *  @return  S16
876  *      -# ROK 
877  *      -# RFAILED 
878  **/
879 #ifdef ANSI
880 PRIVATE S16 rgROMHndlCcchStaRsp
881 (
882 RgCellCb       *cell,
883 RgRguCmnStaRsp *staRsp,
884 RgErrInfo      *err
885 )
886 #else
887 PRIVATE S16 rgROMHndlCcchStaRsp(cell, staRsp, err)
888 RgCellCb       *cell;
889 RgRguCmnStaRsp *staRsp;
890 RgErrInfo      *err;
891 #endif
892 {
893    Pst      schPst;
894    Inst     macInst = cell->macInst - RG_INST_START;
895    RgInfCmnBoRpt boRpt;
896
897    TRC2(rgROMHndlCcchStaRsp);
898
899
900    boRpt.cellSapId  = cell->schInstMap.cellSapId;
901    boRpt.cellId  = staRsp->cellId;
902    boRpt.u.rnti    = staRsp->u.rnti; 
903    boRpt.lcId    = staRsp->lcId; 
904    boRpt.lcType  = staRsp->lcType; 
905    boRpt.bo      = staRsp->bo;
906    rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst);
907    RgMacSchCmnBoUpdt(&schPst, &boRpt);
908
909    RETVALUE(ROK);
910 } /* rgROMHndlCcchStaRsp */
911
912
913 /**
914  * @brief Handler for StaRsp received on RGU for BCCH or PCCH.
915  *
916  * @details
917  *
918  *     Function : rgROMHndlBcchPcchStaRsp
919  *     
920  *     This function shall store the buffer and time to transmit in lcCb.
921  *     
922  *           
923  *  @param[in]  RgCellCb       *cell
924  *  @param[in]  RgRguCmnStaRsp *staRsp
925  *  @param[out] RgErrInfo      *err
926  *  @return  S16
927  *      -# ROK 
928  *      -# RFAILED 
929  **/
930 #ifdef ANSI
931 PRIVATE S16 rgROMHndlBcchPcchStaRsp
932 (
933 RgCellCb       *cell,
934 RgRguCmnStaRsp *staRsp,
935 RgErrInfo      *err
936 )
937 #else
938 PRIVATE S16 rgROMHndlBcchPcchStaRsp(cell, staRsp, err)
939 RgCellCb       *cell;
940 RgRguCmnStaRsp *staRsp;
941 RgErrInfo      *err;
942 #endif
943 {
944    Pst      schPst;
945    RgInfCmnBoRpt boRpt;
946    Inst     macInst = cell->macInst - RG_INST_START;
947
948    TRC2(rgROMHndlBcchPcchStaRsp);
949    cmMemset((U8*)&schPst, (U8)0, sizeof(Pst));
950
951    if (rgDBMChkCmnLcCb(cell, staRsp->lcId) != ROK)
952    {
953       /* Handle lcCb fetch failure */
954       RLOG_ARG1(L_ERROR,DBG_CELLID,cell->cellId,"Invalid LCID:%d",staRsp->lcId);
955       err->errCause = RGERR_ROM_INV_LC_ID;
956       RETVALUE(RFAILED);
957    }
958    /* MS_WORKAROUND : This is to ensure that the queue for BCH is not filled with old BO requests :
959          This assumes that BO is not received more than 4 frames in advance from the enodeb application */
960    if (cell->bcchBchInfo.lcId == staRsp->lcId)
961    {
962       U16 nextBchSfn;
963
964       nextBchSfn = (cell->crntTime.sfn + 4 - (cell->crntTime.sfn%4)) % RG_MAX_SFN;
965       if ((staRsp->u.timeToTx.sfn != nextBchSfn) ||
966          ((staRsp->u.timeToTx.sfn == cell->crntTime.sfn) && (cell->crntTime.subframe >= 7)))
967       {
968         RETVALUE(ROK);
969       }
970    }
971
972    boRpt.cellSapId     = cell->schInstMap.cellSapId;
973    boRpt.cellId     = staRsp->cellId;
974    boRpt.u.timeToTx = staRsp->u.timeToTx; 
975    boRpt.lcId       = staRsp->lcId; 
976    boRpt.lcType     = staRsp->lcType; 
977    boRpt.bo         = staRsp->bo;
978 #ifdef EMTC_ENABLE
979   if(cell->emtcEnable)
980   {
981      if(boRpt.lcType == CM_LTE_LCH_PCCH)
982      {
983         boRpt.emtcDIReason = staRsp->emtcDiReason;
984         boRpt.pnb = staRsp->pnb;
985      }
986   }
987 #endif
988    rgGetPstToInst(&schPst,macInst, cell->schInstMap.schInst);
989    RgMacSchCmnBoUpdt(&schPst, &boRpt);
990
991    RETVALUE(ROK);
992 } /* rgROMHndlBcchPcchStaRsp */
993
994 /* ADD Changes for Downlink UE Timing Optimization */
995 #ifdef LTEMAC_DLUE_TMGOPTMZ
996 /**
997  * @brief Handler for updating DL SF information on receiving
998  *  DL dedicated data, CCCH, BCCH/PCCH data request.
999  *
1000  * @details
1001  *
1002  *     Function : rgROMUpdDLSfRemDataCnt
1003  *     
1004  *           
1005  *  @param[in]  RgCellCb       *cell
1006  *  @param[in]  RgDlSf         *dlSf;
1007  *  @return  S16
1008  *      -# ROK 
1009  *      -# RFAILED 
1010  **/
1011 #ifdef ANSI
1012 PRIVATE S16 rgROMUpdDlSfRemDataCnt
1013 (
1014 RgCellCb       *cellCb,
1015 RgDlSf         *dlSf
1016 )
1017 #else
1018 PRIVATE S16 rgROMUpdDlSfRemDataCnt(cellCb, dlSf)
1019 RgCellCb       *cellCb;
1020 RgDlSf         *dlSf;
1021 #endif
1022 {
1023    RgErrInfo            err;
1024    //Inst                 inst = cellCb->macInst - RG_INST_START;
1025
1026    TRC2(rgROMUpdDlSfRemDataCnt);
1027
1028
1029    if(!dlSf->remDatReqCnt)
1030    {
1031        /*This is an error scenario of RLC generating more data          
1032         * request than the allocation. Do nothing for this. */
1033       RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,
1034             "RX new data while remDatReqCnt is 0 for cell");
1035       RETVALUE(RFAILED);
1036    }
1037
1038    /*Decrement the remaining data request to be received countter
1039      for this SF.
1040      Check if this was the last pending data request for this DL SF.*/
1041     /* Fix[ccpu00126310]: Tracks Data Requests from RLC for both loosely and tight coupled 
1042      RLC-MAC */
1043    if((0 == --dlSf->remDatReqCnt) && !(dlSf->txDone) &&
1044       (RG_TIMEINFO_SAME(cellCb->crntTime, dlSf->schdTime)) && (dlSf->statIndDone))
1045    {
1046       /*Check if we have already received a TTI for this Data,
1047         if that is the case then we need to send TFU Data request 
1048         to PHY */
1049
1050       if (ROK != rgTOMUtlProcDlSf (dlSf, cellCb, &err))
1051       {
1052          RLOG_ARG0(L_ERROR,DBG_CELLID,cellCb->cellId,
1053                "Unable to process downlink subframe for cell");
1054          err.errType = RGERR_ROM_DEDDATREQ;
1055       }
1056
1057       /* Mark this frame as sent */
1058       dlSf->txDone = TRUE;
1059    }
1060
1061    RETVALUE(ROK);
1062 } /* rgROMUpdDlSfRemDataCnt*/
1063 #endif
1064
1065 /**********************************************************************
1066  
1067          End of file
1068 **********************************************************************/