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