U8, U16, U32 data type changes
[o-du/l2.git] / src / 5gnrsch / rg_sch_hdfdd.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 HD-FDD functions
26  
27      File:     rg_sch_hdfdd.c
28  
29 **********************************************************************/
30
31 /** @file rg_sch_hdfdd.c
32 @brief This module handles the  Periodic CQI/PMI/RI, SRS, SR and Half Duplex 
33        functionality 
34 */
35 #ifdef LTEMAC_HDFDD
36 static const char* RLOG_MODULE_NAME="MAC";
37 static int RLOG_MODULE_ID=4096;
38 static int RLOG_FILE_ID=165;
39 #endif
40
41 /* header include files -- defines (.h) */
42 #include "common_def.h"
43 #include "lrg.h"
44 #include "rgr.h"
45 #include "tfu.h"
46 #include "rg_env.h"
47 #include "rg_sch_inf.h"
48 #include "rg_sch_err.h"
49 #include  "rgr.h"
50 #include  "rgm.h"
51 #include "rg_sch.h"
52 #include "rg_sch_cmn.h"
53 #include "rl_interface.h"
54 #include "rl_common.h"
55
56 /* header/extern include files (.x) */
57 #include "tfu.x"           /* RGU types */
58 #include "lrg.x"           /* layer management typedefs for MAC */
59 #include "rgr.x"           /* layer management typedefs for MAC */
60 #include "rgm.x"           /* layer management typedefs for MAC */
61 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
62 #include "rg_sch.x"        /* typedefs for Scheduler */
63 #include "rg_sch_cmn.x"
64
65
66 #ifdef LTEMAC_HDFDD
67 #ifdef __cplusplus
68 extern "C" {
69 #endif /* __cplusplus */
70
71
72 /* @details
73  *
74  *     Function : rgSCHHdFddUeCfg 
75  *
76  *     Invoking Module Processing:
77  *      - This shall be invoked by SCH_GOM at UE Re/configuration. 
78  *        
79  *     Processing Steps:
80  *     - For UE-specific Half Duplex  
81  *      - Allocate the memory and place the UE in cellCb->hdUeLstCp 
82  *        - Update subframes information state to defualt
83  *        - Update subframes information sfn to defualt
84  *     - Return ROK
85  *
86  *  @param[in]  RgSchCellCb  *cell
87  *  @param[in]  RgSchUeCb    *ue
88  *  @param[in]  Bool         *hdFddEnbl
89  *
90  *  @return  S16
91  *      -# ROK
92  *      -# RFAILED
93 */ 
94
95 #ifdef ANSI
96 S16 rgSCHHdFddUeCfg 
97 (
98 RgSchCellCb  *cellCb,
99 RgSchUeCb *ueCb,
100 Bool hdFddEnbl
101 )
102 #else /* ANSI */
103 S16 rgSCHHdFddUeCfg (cellCb, ueCb, hdFddEnbl)
104 RgSchCellCb  *cellCb;
105 RgSchUeCb *ueCb;
106 Bool hdFddEnbl;
107 #endif /* ANSI */
108 {
109    uint8_t sfi;
110
111    RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
112                "rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
113                ueCb->ueId, hdFddEnbl);
114    if(ueCb->hdFddEnbld == TRUE)
115    {
116       if (hdFddEnbl == FALSE)
117       {
118          /* Do not allow switch from HD-FDD to FD-FDD configuration */
119          RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
120                "rgSCHHdFddUeCfg(): HD-FDD  to FD-FDD Configuration is not allowed"
121                "CRNTI:%d",ueCb->ueId);
122       }
123       else
124       {
125          /* If already enabled then it can be second reconfiguration */
126          RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
127                   "rgSCHHdFddUeCfg(): HD-FDD already enabled for this UE"
128                   "CRNTI:%d",ueCb->ueId);
129       }
130       return RFAILED;
131    }
132
133 #ifdef LTEMAC_SPS
134    /* Check is SPS enabled for this UE */
135    if(hdFddEnbl == TRUE &&
136        (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
137         ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
138    {
139       RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
140       "rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
141                "CRNTI:%d",ueCb->ueId);
142       return RFAILED;
143    }
144 #endif
145
146    ueCb->hdFddEnbld = hdFddEnbl;
147    if( hdFddEnbl == TRUE)
148    {
149       rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
150              sizeof(RgSchUeHdFddCb));
151       if (ueCb->hdFddCb != NULLP)
152       {
153          for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
154          {
155             ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
156             ueCb->hdFddCb->subfrm[sfi].sfn      = RG_SCH_HDFDD_INVSFN;
157          }
158          /* Add this UE to list maintained in CellCb */
159          /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
160       }
161       else
162       {
163          RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
164                "rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
165                "CRNTI:%d",ueCb->ueId);
166          return RFAILED;
167       }
168    }
169    return ROK;
170 }/*rgSCHHdFddUeCfg*/
171
172
173 /* @brief Frees Half Duplex  related data structures
174  *
175  * @details
176  *
177  *     Function : rgSCHHdFddUeDel
178  *
179  *     Invoking Module Processing:
180  *      - This shall be invoked by SCH_GOM at Ue deletion.
181  *
182  *     Processing Steps:
183  *       - if Half Duplex is enabled
184  *       - if (ueCb->hdFddCb != NULL)
185  *        - Remove ue from  cellCb->hdUeLstCp;
186  *        - Dellocate memory 
187  *       - else
188  *        - Nothing to do
189  *      - Return ROK
190  *  @param[in]  RgSchCellCb  *cell
191  *  @param[in]  RgSchUeCb    *ue
192  *
193  *  @return ( S16
194  *      -# ROK
195 *
196 */
197 #ifdef ANSI
198 S16 rgSCHHdFddUeDel 
199 (
200 RgSchCellCb *cellCb,
201 RgSchUeCb   *ueCb
202 )
203 #else /* ANSI */
204 S16 rgSCHHdFddUeDel(cellCb, ueCb)
205 RgSchCellCb *cellCb;
206 RgSchUeCb   *ueCb;
207 #endif /* ANSI */
208 {
209
210    RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
211              " rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
212              ueCb->ueId, ueCb->hdFddEnbld);
213
214
215     if (ueCb->hdFddCb)
216     {
217        /* ccpu00117052 - MOD - Passing double pointer
218        for proper NULLP assignment*/
219        rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(ueCb->hdFddCb)),
220              sizeof(RgSchUeHdFddCb));   
221        ueCb->hdFddEnbld = FALSE;
222     }
223
224     return ROK;
225 } /* rgSCHHdFddUeDel */
226
227
228
229 #ifdef TFU_UPGRADE
230 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
231  * expecting .
232  *
233  * @details
234  *
235  *     Function: rgSCHCmnHdFddPtUlMrk 
236  *     Purpose:  Updation of Periodic CQI/PMI, SRS and SR tranmission
237  *               instance updates
238  *               for HD FDD UEs
239  *  @param[in]  RgSchCellCb *cell
240  *  @return    None
241  */
242
243 #ifdef ANSI
244 Void rgSCHCmnHdFddPtUlMrk 
245 (
246 RgSchCellCb *cellCb
247 )
248 #else /* ANSI */
249 Void rgSCHCmnHdFddPtUlMrk (cellCb)
250 RgSchCellCb *cellCb;
251 #endif /* ANSI */
252 {
253    uint16_t                    sfn; /* System Frame Number */
254    uint32_t                    pti; /* Index into Periodic table */
255    uint16_t                    sfi; /* Index into HDFDD state table */
256    CmLListCp              *cqiLst;
257    CmLListCp              *srsLst;
258    CmLListCp              *srLst;
259    CmLListCp              *riLst;
260    CmLList                *cqiNode;
261    CmLList                *srsNode;
262    CmLList                *srNode;
263    CmLList                *riNode;
264    CmLteTimingInfo        timeInfo;
265    RgSchUePCqiCb          *cqiCb = NULLP;
266    RgSchUePCqiCb          *riCb = NULLP;
267
268
269    timeInfo = cellCb->crntTime;
270
271    /* Determine indexes */
272    pti = RG_SCH_HDFDD_GETPTI(timeInfo);
273    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_DELTA);
274    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_DELTA);
275
276    /* Get PT entries for */
277    cqiLst = &cellCb->pCqiSrsSrLst[pti].cqiLst;
278    srsLst = &cellCb->pCqiSrsSrLst[pti].srsLst;
279    srLst  = &cellCb->pCqiSrsSrLst[pti].srLst;
280    riLst  = &cellCb->pCqiSrsSrLst[pti].riLst;
281
282    /* Get first node in each list */
283    CM_LLIST_FIRST_NODE(cqiLst, cqiNode);
284    CM_LLIST_FIRST_NODE(srsLst, srsNode);
285    CM_LLIST_FIRST_NODE(riLst,  riNode);
286    CM_LLIST_FIRST_NODE(srLst,  srNode);
287
288    /* Mark corresponding the subframe as uplink control */
289    while ((NULLP != cqiNode ) &&
290          (NULLP != srsNode  ) &&
291          (NULLP != srNode   )  &&
292          (NULLP != riNode   ))
293    {
294      cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
295      RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
296                      RG_SCH_HDFDD_UL, sfn, sfi);
297       /* SRS Transmission instances */
298       RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srsNode->node,
299                      RG_SCH_HDFDD_UL, sfn, sfi);
300       /* SR Transmission instances */
301       RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srNode->node,
302                      RG_SCH_HDFDD_UL, sfn, sfi);
303       /* RI Transmission instances */
304      riCb = (RgSchUePCqiCb *)(riNode->node);
305      RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
306                      RG_SCH_HDFDD_UL, sfn, sfi);
307
308       /* Get next UeCb for all lists */
309       CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
310       CM_LLIST_NEXT_NODE(srsLst, srsNode);
311       CM_LLIST_NEXT_NODE(srLst, srNode);
312       CM_LLIST_NEXT_NODE(riLst, riNode);
313    }
314
315    while ( NULLP != cqiNode)
316    {
317       /* CQI/PMI Transmission instances */
318       cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
319       RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
320                      RG_SCH_HDFDD_UL, sfn, sfi);
321       CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
322    }
323    while( NULLP != srsNode)
324    {
325       /* SRS Transmission instances */
326       RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srsNode->node),
327                      RG_SCH_HDFDD_UL, sfn, sfi);
328       CM_LLIST_NEXT_NODE(srsLst, srsNode);
329    }
330    while( NULLP != srNode)
331    {
332       /* SR Transmission instances */
333       RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srNode->node),
334                      RG_SCH_HDFDD_UL, sfn, sfi);
335       CM_LLIST_NEXT_NODE(srLst, srNode);
336    }
337    while( NULLP != riNode)
338    {
339       /* RI Transmission instances */
340      riCb = (RgSchUePCqiCb *)(riNode->node);
341      RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
342                      RG_SCH_HDFDD_UL, sfn, sfi);
343      CM_LLIST_NEXT_NODE(riLst, riNode);
344    }
345
346    return;
347 } /* rgSCHCmnHdFddPtUlMrk */
348 #endif /* ifdef TFU_UPGRADE */
349
350
351
352 /* @brief Decides whether UE can be allowed for DL in given subframe
353  *
354  * @details
355  *
356  *     Function : rgSCHCmnHdFddChkUlAllow 
357  *
358  *     Invoking Module Processing:
359  *      - This shall be invoked by schedulars before allocating  UL grants .
360  *
361  *     Processing Steps:
362  *       - if Half Duplex is enabled
363  *       - If ue->sf[reqsf].state is "DONWLINK"
364  *            set alloweUlSch=FALSE
365  *       - else
366  *            set alloweUlSch=TRUE
367  *        This function Marking for BCCH/PCCH occasions is also done
368  *      - Return ROK
369  *  @param[in]  RgSchCellCb  *cell
370  *  @param[in]  RgSchUeCb    *ue
371  *
372  *  @return    None
373  *
374  */
375 #ifdef ANSI
376 Void rgSCHCmnHdFddChkUlAllow
377
378  RgSchCellCb *cellCb,
379  RgSchUeCb   *ueCb,
380  uint8_t          *allow
381 )
382 #else /* ANSI */
383 Void rgSCHCmnHdFddChkUlAllow ( cellCb, ueCb, allow)
384 RgSchCellCb *cellCb;
385 RgSchUeCb   *ueCb;
386 uint8_t          *allow;
387 #endif /* ANSI */
388 {
389    uint16_t              sfn;
390    uint16_t              sfi;
391    CmLteTimingInfo  timeInfo;
392    RgSchDlSf        *sf = NULLP; /* Dl subframe info */
393    uint8_t               ulOffset
394
395    RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId, 
396             " rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
397
398    *allow = FALSE;
399
400    timeInfo = cellCb->crntTime;
401
402    ulOffset = RGSCH_PDCCH_PUSCH_DELTA - 
403           TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
404    RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset);
405
406    /* Set default value */
407    *allow = FALSE;
408
409    /* Validate condition 1 */
410    /* For (curretn time + DL_DELTA)th sf */
411
412    /* Also get subframe pointer to fetch Common Ch allocation */
413    sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
414
415    sfn = timeInfo.sfn;
416    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
417
418    /* Validate condition 2 */
419    if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
420    {
421          /* Common channel scheduled */
422          /* Mark the BCCH/PCCH occasion */
423          RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
424          RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
425             "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
426             ueCb->ueId);
427    }
428    if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
429          (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA ||
430           ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLCNTRL))
431    {
432       /* Downlink scheduled */
433       *allow = FALSE;
434       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
435                "rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
436                ueCb->ueId);
437       return;
438    }
439
440    /* Validate condition 3 */
441    /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf
442       - i.e. next HARQ Feedback occasion */
443    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
444    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
445    if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
446        ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
447    {
448       /* No place for HARQ feedback */
449       *allow = FALSE;
450       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
451          "rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
452          ueCb->ueId);
453       return;
454
455    }
456    /* Validate condition 4 */
457    /* For (curretn time + DL_DELTA - HRQ_DELTA)th sf
458       - i.e. previous HARQ Feedback occasion */
459    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
460    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
461    if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
462        ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
463    {
464       *allow = FALSE;
465       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
466                " rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
467                ueCb->ueId);
468       return;
469
470    }
471    /* Validate condition 5 */
472    /* For (curretn time + DL_DELTA - 1)th sf -i.e. Guard time */
473    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
474    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
475    if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
476        (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA))
477    {
478       /* This subframe may be a switching gaurd time */
479       *allow = FALSE;
480       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
481              " rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
482              ueCb->ueId);
483       return;
484
485    }
486    /* Adition guard time rule check: Above check is only for PDSCH, lets check
487       is there is any BCCH/PCCH data scheduled */
488    RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, 
489                       (ulOffset - RG_SCH_HDFDD_GRDTIM_DUR));
490    /* Also get subframe pointer to fetch Common Ch allocation */
491    sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
492    if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
493    {
494       /* Common channel scheduled */
495       /* Mark the BCCH/PCCH occasion */
496       RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
497       *allow = FALSE;
498       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
499          "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
500          ueCb->ueId);
501       return;
502
503    }
504
505    /* All validation done. Safe to for UL */
506    *allow = TRUE;
507    return;
508 } /* rgSCHCmnHdFddChkUlAllow */
509
510
511  /* @brief Decides whether UE can be allowed for UL in given subframe
512  *
513  * @details
514  *
515  *     Function : rgSCHCmnHdFddChkDlAllow
516  *
517  *     Invoking Module Processing:
518  *      - This shall be invoked by schedulars before allocating for DL.
519  *
520  *     Processing Steps:
521  *          Condition 1:  subframe n + DL_DELTA should not be uplink
522  *          Condition 2:  subframe n+ DL_DELTA + 1 should meet guard time
523  *                        creation rule. For more
524  *                        information refer to section "2.25.7.1 Guard time
525  *                        creation rule"
526  *          Condition 3:  subframe n + DL_DELTA + HRQ_DELTA should not be
527  *                        downlink so that downlink data (HARQ Feedback)
528  *                        can be received in next 4 subframe. {n + 7} Above
529  *                        conditions have to
530  *                        be validated by taking SFN number into consideration.
531  *          if all conditions are met then *allow is set to TRUE or lese to
532  *          FALSE.
533  *          if hd-fdd is not anabled for this UE, then *allow is always TRUE.
534  *   
535  *   Returns None
536  *  @param[in]  RgSchCellCb  *cellCb
537  *  @param[in]  RgSchUeCb    *ueCb
538  *  @param[in]  CmLteTimingInfo    *timeInfo
539  *  @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
540  *                   Valdity of this pointer is not done in this function
541  *
542  */
543 #ifdef ANSI
544 Void rgSCHCmnHdFddChkDlAllow 
545 (
546 RgSchCellCb *cellCb,
547 RgSchUeCb *ueCb,
548 Bool *allow /* Valdity of this pointer is not done in this function */
549 )
550 #else /* ANSI */
551 Void rgSCHCmnHdFddChkDlAllow ( cellCb, ueCb, allow)
552 RgSchCellCb *cellCb;
553 RgSchUeCb *ueCb;
554 Bool *allow; /* Valdity of this pointer is not done in this function */
555 #endif /* ANSI */
556 {
557    uint16_t     sfn;
558    uint16_t     sfi;
559    RgSchDlSf *sf = NULLP; /* Dl subframe info */
560    CmLteTimingInfo timeInfo;
561    CmLteTimingInfo tempTimeInfo;
562
563    *allow = FALSE;
564
565    timeInfo = cellCb->crntTime;
566    RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
567
568    RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
569             "rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
570
571    /* Also get subframe pointer to fetch Common Ch allocation */
572    sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
573
574    /* Validate condition 1 */
575    /* For (curretn time + DL_DELTA)th sf */
576    sfn = timeInfo.sfn;
577    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
578
579    if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
580         (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
581    {
582       /* Uplink scheduled */
583       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
584                "rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
585       *allow = FALSE;
586       return;
587    }
588
589    /* It is not validation, but BCCH/PCCH marking is done here */
590    if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
591    {
592       /* Common channel scheduled */
593       RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
594    }
595
596    /* Validate condition 2 */
597    /* For (curretn time + DL_DELTA + 1)th sf -i.e. Guard time */
598    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
599    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
600    if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
601           (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
602    {
603       /* This subframe may be a switching guard time */
604       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
605               " rgSCHCmnHdFddChkDlAllow: Guard time rule not met, ueId=%d ",
606               ueCb->ueId);
607       *allow = FALSE;
608       return;
609    }
610
611    /* Validate condition 3 */
612    /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
613       Feedback occasion */
614
615    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
616    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
617
618    /* First check for any Common channel info is scheduled */
619    RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL)
620    /* Also get subframe pointer to fetch Common Ch allocation */
621    sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
622    if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
623    {
624          /* Common channel scheduled */
625       /* Do the marking for this subframe */
626       RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
627       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
628               "rgSCHCmnHdFddChkDlAllow: Possible systemInfo, ueId=%d ",
629               ueCb->ueId);
630    }
631
632    /* Check for actual validation condition 3 */
633    if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
634        ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
635    {
636       /* No place for HARQ feedback */
637       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,  
638             "rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
639             ueCb->ueId);
640       *allow = FALSE;
641
642       /* Mark this sf as DLCNTRL */
643       ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
644       return;
645    }
646
647
648    /* If we are here then, subframe at HARQth location can be UL.
649       But check if Guard violation is done */
650    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
651    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
652    /* check for any Common channel info is scheduled */
653    RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, (RG_SCH_CMN_HARQ_INTERVAL-1))
654    /* Also get subframe pointer to fetch Common Ch allocation */
655    sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
656    if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
657    {
658          /* Common channel scheduled */
659       /* Do the marking for this subframe */
660       RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
661       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
662               "rgSCHCmnHdFddChkDlAllow: (GT) Possible systemInfo, ueId=%d ",
663               ueCb->ueId);
664    }
665
666    if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
667        ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
668    {
669       /* No place for HARQ feedback */
670       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
671             "rgSCHCmnHdFddChkDlAllow: (GT) No place for HARQ feedback,"
672              "ueId=%d ",ueCb->ueId);
673
674       *allow = FALSE;
675       return;
676    }
677    /* First check for any Common channel info is scheduled */
678
679    *allow = TRUE;
680    /* All validation done. Safe to for DL */
681    return;
682 } /* rgSCHCmnHdFddChkDlAllow */
683
684
685
686 /* @brief Decides whether NACK can be sent in a given subrame
687  *
688  * @details
689  *
690  *     Function : rgSCHCmnHdFddChkNackAllow
691  *
692  *     Invoking Module Processing:
693  *      - This shall be invoked by schedulars.
694  *
695  *  @param[in]  RgSchUeCb    *ue
696  *
697  *  @return  None
698  *
699  */
700
701 #ifdef ANSI
702 Void rgSCHCmnHdFddChkNackAllow
703 (
704 RgSchCellCb *cellCb,
705 RgSchUeCb   *ueCb,
706 CmLteTimingInfo  timeInfo,
707 Bool *sndNACK
708 )
709 #else /* ANSI */
710 Void rgSCHCmnHdFddChkNackAllow(cellCb, ueCb, timeInfo, sndNACK)
711 RgSchCellCb *cellCb;
712 RgSchUeCb   *ueCb;
713 CmLteTimingInfo  timeInfo;
714 Bool *sndNACK;
715 #endif /* ANSI */
716 {
717    RgSchDlSf *sf;
718    CmLteTimingInfo  tempTimeInfo;
719
720    /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
721
722    *sndNACK = FALSE;
723
724    /* Determine SFN and sf index for current subframe.
725       Note: Round function used as example */
726    tempTimeInfo = timeInfo;
727    RGSCH_INCR_SUB_FRAME(tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL);
728
729    /* Also get subframe pointer to fetch Common Ch allocation */
730    sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
731
732    /* Check is this subframe has any Common Channel info scheduled */
733    if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
734    {
735       /* Yes, Cannot send NACK */
736       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
737                "rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
738                ueCb->ueId);
739       *sndNACK = FALSE;
740    }
741    else
742    {
743       /* safe, Send NACK */
744       RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
745                "rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
746                ueCb->ueId);
747       *sndNACK = TRUE;
748    }
749
750    return;
751 } /* rgSCHCmnHdFddChkNackAllow */
752
753
754
755
756  /* @brief makes final marking for HD-FDD UL allocations
757  *
758  * @details
759  *
760  *     Function : rgSCHCmnHdFddUpdULMark
761  *
762  *     Invoking Module Processing:
763  *      - This shall be invoked by schedulars at the time of UL allocation
764  *        finalization.
765  *
766  *     Processing Steps:
767  *   
768  *  @param[in]  RgSchCellCb  *cellCb
769  *  @param[in]  RgSchUeCb    *ueCb
770  *  @param[in]  CmLteTimingInfo    *timeInfo
771  *  @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
772  *             Valdity of this pointer is not done in this function.
773  *
774  *  @return  None
775  */
776 #ifdef ANSI
777 Void rgSCHCmnHdFddUpdULMark
778 (
779 RgSchCellCb *cellCb,
780 RgSchUeCb   *ueCb
781 )
782 #else /* ANSI */
783 Void rgSCHCmnHdFddUpdULMark ( cellCb, ueCb)
784 RgSchCellCb *cellCb;
785 RgSchUeCb   *ueCb;
786 #endif /* ANSI */
787 {
788
789    uint16_t sfn;
790    uint16_t sfi;
791    CmLteTimingInfo  timeInfo;
792    uint8_t   ulOffset;
793
794    ulOffset = RGSCH_PDCCH_PUSCH_DELTA - 
795               TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
796    RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset)
797
798
799    /* Mark (n + UL_DELTA)th subframe as UL */
800    sfn = timeInfo.sfn;
801    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
802
803    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
804
805    /* Mark (n + UL_DELTA + HARQ_DELTA)th subframe as DL */
806    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
807    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
808    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
809
810    /* Mark (n + UL_DELTA - HARQ_DELTA)th subframe as DL */
811    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
812    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
813    if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_DLDATA)
814    {
815       RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
816    }
817
818    /* Mark (n + UL_DELTA - 1)th subframe as DL_CNTRL */
819    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
820    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
821    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
822
823    /* Remove marking for older subframes */
824
825    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (S16)(ulOffset * -1));
826    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (ulOffset * -1));
827    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_NOSCHD, RG_SCH_HDFDD_INVSFN, sfi);
828
829    return;
830 } /* rgSCHCmnHdFddUpdULMark */
831
832
833
834
835  /* @brief makes final marking for HD-FDD DL allocations
836  *
837  * @details
838  *
839  *     Function : rgSCHCmnHdFddUpdDLMark
840  *
841  *     Invoking Module Processing:
842  *      - This shall be invoked by schedulars at the time of DL allocation
843  *          finalization.
844  *
845  *     Processing Steps:
846  *   
847  *  @param[in]  RgSchCellCb  *cellCb
848  *  @param[in]  RgSchUeCb    *ueCb
849  *  @param[in]  CmLteTimingInfo    *timeInfo
850  *  @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowed.
851  *                Valdity of this pointer is not done in this function
852  *
853  *  @return  None
854  */
855
856 #ifdef ANSI
857 Void rgSCHCmnHdFddUpdDLMark
858 (
859 RgSchCellCb *cellCb,
860 RgSchUeCb   *ueCb
861 )
862 #else /* ANSI */
863 Void rgSCHCmnHdFddUpdDLMark (cellCb, ueCb)
864 RgSchCellCb *cellCb;
865 RgSchUeCb   *ueCb;
866 #endif /* ANSI */
867 {
868
869    uint16_t sfn;
870    uint16_t sfi;
871    CmLteTimingInfo  timeInfo;
872
873    timeInfo = cellCb->crntTime;
874    RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
875
876    /* Mark (n + DL_DELTA)th subframe as DL */
877    sfn = timeInfo.sfn;
878    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
879
880    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
881
882    /* Mark (n + 1)th subframe as DL_CNTRL */
883    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
884    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
885    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
886
887    /* Mark (n + DL_DELTA + HARQ_DELTA )th subframe as UL */
888    RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
889    RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
890    RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
891
892    /* Mark (n + DL_DELTA + HARQ_DELTA - 1)th subframe
893       as DL control for Guard period */
894    RG_SCH_HDFDD_GETSFN(sfn, timeInfo,
895           (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
896    RG_SCH_HDFDD_GETSFI(sfi, timeInfo,
897          (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
898    if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
899    {
900       RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
901    }
902
903    return;
904 } /* rgSCHCmnHdFddUpdDLMark */
905
906
907  /* @brief determines effective SFN
908  *
909  * @details
910  *
911  *     Function : rgSCHHdFddGetSfn
912  *
913  *     Invoking Module Processing:
914  *       Any HD-FDD module can invoke this function.
915  *
916  *     Processing Steps:
917  *   
918  *  @param[out]  *sfn uint32_t
919  *  @param[in]  timeInfo timing information subframe of interest 
920  *  @param[in]  offsest  Offest with w.r.t which SFN has to be determined
921  *
922  *  @return  None
923  */
924
925 #ifdef ANSI
926 Void rgSCHHdFddGetSfn
927 (
928  uint16_t *sfn,
929  CmLteTimingInfo  timeInfo,
930  S16 offset
931 )
932 #else /* ANSI */
933 Void rgSCHHdFddGetSfn (sfn, timeInfo, offset)
934  uint16_t *sfn;
935  CmLteTimingInfo  timeInfo;
936  S16 offset;
937 #endif /* ANSI */
938 {
939    uint16_t tempSfn;
940    S16 tempSfCount;
941
942    if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
943    {
944       /* Increament to number of times of SFNs that can be possible
945          with this offset */
946       tempSfn = (timeInfo.sfn +
947                 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
948                 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
949    }
950    else
951    {
952       if(((S16)(timeInfo.subframe) + offset) < 0)
953       {
954          /* If negative, then definitely at least previous SFN */
955          tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
956
957          /* Now find how many more times we need to decreament */
958          tempSfCount = timeInfo.subframe + offset;
959          RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
960       }
961       else
962       {
963          /* No change in sfn */
964          tempSfn = timeInfo.sfn;
965       }
966    }
967    *sfn = tempSfn;
968
969    return;
970 } /* End of rgSCHHdFddGetSfn */
971
972
973 #ifdef __cplusplus
974 }
975  /* extern C */
976 #endif /* __cplusplus */
977
978 #endif /* LTEMAC_HDFDD */
979
980
981
982
983 /**********************************************************************
984  
985          End of file
986 **********************************************************************/