1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for HD-FDD functions
29 **********************************************************************/
31 /** @file rg_sch_hdfdd.c
32 @brief This module handles the Periodic CQI/PMI/RI, SRS, SR and Half Duplex
36 static const char* RLOG_MODULE_NAME="MAC";
37 static int RLOG_MODULE_ID=4096;
38 static int RLOG_FILE_ID=165;
41 /* header include files -- defines (.h) */
42 #include "envopt.h" /* environment options */
43 #include "envdep.h" /* environment dependent */
44 #include "envind.h" /* environment independent */
45 #include "gen.h" /* general layer */
46 #include "ssi.h" /* system service interface */
47 #include "cm_hash.h" /* common hash list */
48 #include "cm_llist.h" /* common linked list library */
49 #include "cm_err.h" /* common error */
50 #include "cm_lte.h" /* common LTE */
55 #include "rg_sch_inf.h"
56 #include "rg_sch_err.h"
60 #include "rg_sch_cmn.h"
61 #include "rl_interface.h"
62 #include "rl_common.h"
64 /* header/extern include files (.x) */
65 #include "gen.x" /* general layer typedefs */
66 #include "ssi.x" /* system services typedefs */
67 #include "cm5.x" /* common timers */
68 #include "cm_hash.x" /* common hash list */
69 #include "cm_lib.x" /* common library */
70 #include "cm_llist.x" /* common linked list */
71 #include "cm_mblk.x" /* memory management */
72 #include "cm_tkns.x" /* common tokens */
73 #include "cm_lte.x" /* common tokens */
74 #include "tfu.x" /* RGU types */
75 #include "lrg.x" /* layer management typedefs for MAC */
76 #include "rgr.x" /* layer management typedefs for MAC */
77 #include "rgm.x" /* layer management typedefs for MAC */
78 #include "rg_sch_inf.x" /* typedefs for Scheduler */
79 #include "rg_sch.x" /* typedefs for Scheduler */
80 #include "rg_sch_cmn.x"
86 #endif /* __cplusplus */
91 * Function : rgSCHHdFddUeCfg
93 * Invoking Module Processing:
94 * - This shall be invoked by SCH_GOM at UE Re/configuration.
97 * - For UE-specific Half Duplex
98 * - Allocate the memory and place the UE in cellCb->hdUeLstCp
99 * - Update subframes information state to defualt
100 * - Update subframes information sfn to defualt
103 * @param[in] RgSchCellCb *cell
104 * @param[in] RgSchUeCb *ue
105 * @param[in] Bool *hdFddEnbl
113 PUBLIC S16 rgSCHHdFddUeCfg
120 PUBLIC S16 rgSCHHdFddUeCfg (cellCb, ueCb, hdFddEnbl)
127 TRC3(rgSCHHdFddUeCfg)
129 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
130 "rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
131 ueCb->ueId, hdFddEnbl);
132 if(ueCb->hdFddEnbld == TRUE)
134 if (hdFddEnbl == FALSE)
136 /* Do not allow switch from HD-FDD to FD-FDD configuration */
137 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
138 "rgSCHHdFddUeCfg(): HD-FDD to FD-FDD Configuration is not allowed"
139 "CRNTI:%d",ueCb->ueId);
143 /* If already enabled then it can be second reconfiguration */
144 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
145 "rgSCHHdFddUeCfg(): HD-FDD already enabled for this UE"
146 "CRNTI:%d",ueCb->ueId);
152 /* Check is SPS enabled for this UE */
153 if(hdFddEnbl == TRUE &&
154 (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
155 ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
157 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
158 "rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
159 "CRNTI:%d",ueCb->ueId);
164 ueCb->hdFddEnbld = hdFddEnbl;
165 if( hdFddEnbl == TRUE)
167 rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
168 sizeof(RgSchUeHdFddCb));
169 if (ueCb->hdFddCb != NULLP)
171 for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
173 ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
174 ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN;
176 /* Add this UE to list maintained in CellCb */
177 /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
181 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
182 "rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
183 "CRNTI:%d",ueCb->ueId);
191 /* @brief Frees Half Duplex related data structures
195 * Function : rgSCHHdFddUeDel
197 * Invoking Module Processing:
198 * - This shall be invoked by SCH_GOM at Ue deletion.
201 * - if Half Duplex is enabled
202 * - if (ueCb->hdFddCb != NULL)
203 * - Remove ue from cellCb->hdUeLstCp;
208 * @param[in] RgSchCellCb *cell
209 * @param[in] RgSchUeCb *ue
216 PUBLIC S16 rgSCHHdFddUeDel
222 PUBLIC S16 rgSCHHdFddUeDel(cellCb, ueCb)
227 TRC3(rgSCHHdFddUeDel)
229 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
230 " rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
231 ueCb->ueId, ueCb->hdFddEnbld);
236 /* ccpu00117052 - MOD - Passing double pointer
237 for proper NULLP assignment*/
238 rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(ueCb->hdFddCb)),
239 sizeof(RgSchUeHdFddCb));
240 ueCb->hdFddEnbld = FALSE;
244 } /* rgSCHHdFddUeDel */
249 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
254 * Function: rgSCHCmnHdFddPtUlMrk
255 * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission
258 * @param[in] RgSchCellCb *cell
263 PUBLIC Void rgSCHCmnHdFddPtUlMrk
268 PUBLIC Void rgSCHCmnHdFddPtUlMrk (cellCb)
272 U16 sfn; /* System Frame Number */
273 U32 pti; /* Index into Periodic table */
274 U16 sfi; /* Index into HDFDD state table */
283 CmLteTimingInfo timeInfo;
284 RgSchUePCqiCb *cqiCb = NULLP;
285 RgSchUePCqiCb *riCb = NULLP;
287 TRC3(rgSCHCmnHdFddPtUlMrk)
289 timeInfo = cellCb->crntTime;
291 /* Determine indexes */
292 pti = RG_SCH_HDFDD_GETPTI(timeInfo);
293 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_DELTA);
294 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_DELTA);
296 /* Get PT entries for */
297 cqiLst = &cellCb->pCqiSrsSrLst[pti].cqiLst;
298 srsLst = &cellCb->pCqiSrsSrLst[pti].srsLst;
299 srLst = &cellCb->pCqiSrsSrLst[pti].srLst;
300 riLst = &cellCb->pCqiSrsSrLst[pti].riLst;
302 /* Get first node in each list */
303 CM_LLIST_FIRST_NODE(cqiLst, cqiNode);
304 CM_LLIST_FIRST_NODE(srsLst, srsNode);
305 CM_LLIST_FIRST_NODE(riLst, riNode);
306 CM_LLIST_FIRST_NODE(srLst, srNode);
308 /* Mark corresponding the subframe as uplink control */
309 while ((NULLP != cqiNode ) &&
310 (NULLP != srsNode ) &&
311 (NULLP != srNode ) &&
314 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
315 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
316 RG_SCH_HDFDD_UL, sfn, sfi);
317 /* SRS Transmission instances */
318 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srsNode->node,
319 RG_SCH_HDFDD_UL, sfn, sfi);
320 /* SR Transmission instances */
321 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srNode->node,
322 RG_SCH_HDFDD_UL, sfn, sfi);
323 /* RI Transmission instances */
324 riCb = (RgSchUePCqiCb *)(riNode->node);
325 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
326 RG_SCH_HDFDD_UL, sfn, sfi);
328 /* Get next UeCb for all lists */
329 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
330 CM_LLIST_NEXT_NODE(srsLst, srsNode);
331 CM_LLIST_NEXT_NODE(srLst, srNode);
332 CM_LLIST_NEXT_NODE(riLst, riNode);
335 while ( NULLP != cqiNode)
337 /* CQI/PMI Transmission instances */
338 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
339 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
340 RG_SCH_HDFDD_UL, sfn, sfi);
341 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
343 while( NULLP != srsNode)
345 /* SRS Transmission instances */
346 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srsNode->node),
347 RG_SCH_HDFDD_UL, sfn, sfi);
348 CM_LLIST_NEXT_NODE(srsLst, srsNode);
350 while( NULLP != srNode)
352 /* SR Transmission instances */
353 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srNode->node),
354 RG_SCH_HDFDD_UL, sfn, sfi);
355 CM_LLIST_NEXT_NODE(srLst, srNode);
357 while( NULLP != riNode)
359 /* RI Transmission instances */
360 riCb = (RgSchUePCqiCb *)(riNode->node);
361 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
362 RG_SCH_HDFDD_UL, sfn, sfi);
363 CM_LLIST_NEXT_NODE(riLst, riNode);
367 } /* rgSCHCmnHdFddPtUlMrk */
368 #endif /* ifdef TFU_UPGRADE */
372 /* @brief Decides whether UE can be allowed for DL in given subframe
376 * Function : rgSCHCmnHdFddChkUlAllow
378 * Invoking Module Processing:
379 * - This shall be invoked by schedulars before allocating UL grants .
382 * - if Half Duplex is enabled
383 * - If ue->sf[reqsf].state is "DONWLINK"
384 * set alloweUlSch=FALSE
386 * set alloweUlSch=TRUE
387 * This function Marking for BCCH/PCCH occasions is also done
389 * @param[in] RgSchCellCb *cell
390 * @param[in] RgSchUeCb *ue
396 PUBLIC Void rgSCHCmnHdFddChkUlAllow
403 PUBLIC Void rgSCHCmnHdFddChkUlAllow ( cellCb, ueCb, allow)
411 CmLteTimingInfo timeInfo;
412 RgSchDlSf *sf = NULLP; /* Dl subframe info */
415 TRC3(rgSCHCmnHdFddChkUlAllow)
417 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
418 " rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
422 timeInfo = cellCb->crntTime;
424 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
425 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
426 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset);
428 /* Set default value */
431 /* Validate condition 1 */
432 /* For (curretn time + DL_DELTA)th sf */
434 /* Also get subframe pointer to fetch Common Ch allocation */
435 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
438 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
440 /* Validate condition 2 */
441 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
443 /* Common channel scheduled */
444 /* Mark the BCCH/PCCH occasion */
445 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
446 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
447 "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
450 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
451 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA ||
452 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLCNTRL))
454 /* Downlink scheduled */
456 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
457 "rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
462 /* Validate condition 3 */
463 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf
464 - i.e. next HARQ Feedback occasion */
465 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
466 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
467 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
468 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
470 /* No place for HARQ feedback */
472 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
473 "rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
478 /* Validate condition 4 */
479 /* For (curretn time + DL_DELTA - HRQ_DELTA)th sf
480 - i.e. previous HARQ Feedback occasion */
481 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
482 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
483 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
484 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
487 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
488 " rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
493 /* Validate condition 5 */
494 /* For (curretn time + DL_DELTA - 1)th sf -i.e. Guard time */
495 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
496 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
497 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
498 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA))
500 /* This subframe may be a switching gaurd time */
502 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
503 " rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
508 /* Adition guard time rule check: Above check is only for PDSCH, lets check
509 is there is any BCCH/PCCH data scheduled */
510 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo,
511 (ulOffset - RG_SCH_HDFDD_GRDTIM_DUR));
512 /* Also get subframe pointer to fetch Common Ch allocation */
513 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
514 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
516 /* Common channel scheduled */
517 /* Mark the BCCH/PCCH occasion */
518 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
520 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
521 "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
527 /* All validation done. Safe to for UL */
530 } /* rgSCHCmnHdFddChkUlAllow */
533 /* @brief Decides whether UE can be allowed for UL in given subframe
537 * Function : rgSCHCmnHdFddChkDlAllow
539 * Invoking Module Processing:
540 * - This shall be invoked by schedulars before allocating for DL.
543 * Condition 1: subframe n + DL_DELTA should not be uplink
544 * Condition 2: subframe n+ DL_DELTA + 1 should meet guard time
545 * creation rule. For more
546 * information refer to section "2.25.7.1 Guard time
548 * Condition 3: subframe n + DL_DELTA + HRQ_DELTA should not be
549 * downlink so that downlink data (HARQ Feedback)
550 * can be received in next 4 subframe. {n + 7} Above
552 * be validated by taking SFN number into consideration.
553 * if all conditions are met then *allow is set to TRUE or lese to
555 * if hd-fdd is not anabled for this UE, then *allow is always TRUE.
558 * @param[in] RgSchCellCb *cellCb
559 * @param[in] RgSchUeCb *ueCb
560 * @param[in] CmLteTimingInfo *timeInfo
561 * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowedi.
562 * Valdity of this pointer is not done in this function
566 PUBLIC Void rgSCHCmnHdFddChkDlAllow
570 Bool *allow /* Valdity of this pointer is not done in this function */
573 PUBLIC Void rgSCHCmnHdFddChkDlAllow ( cellCb, ueCb, allow)
576 Bool *allow; /* Valdity of this pointer is not done in this function */
581 RgSchDlSf *sf = NULLP; /* Dl subframe info */
582 CmLteTimingInfo timeInfo;
583 CmLteTimingInfo tempTimeInfo;
585 TRC3(rgSCHCmnHdFddChkDlAllow)
589 timeInfo = cellCb->crntTime;
590 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
592 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
593 "rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
595 /* Also get subframe pointer to fetch Common Ch allocation */
596 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
598 /* Validate condition 1 */
599 /* For (curretn time + DL_DELTA)th sf */
601 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
603 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
604 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
606 /* Uplink scheduled */
607 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
608 "rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
613 /* It is not validation, but BCCH/PCCH marking is done here */
614 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
616 /* Common channel scheduled */
617 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
620 /* Validate condition 2 */
621 /* For (curretn time + DL_DELTA + 1)th sf -i.e. Guard time */
622 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
623 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
624 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
625 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
627 /* This subframe may be a switching guard time */
628 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
629 " rgSCHCmnHdFddChkDlAllow: Guard time rule not met, ueId=%d ",
635 /* Validate condition 3 */
636 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
639 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
640 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
642 /* First check for any Common channel info is scheduled */
643 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL)
644 /* Also get subframe pointer to fetch Common Ch allocation */
645 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
646 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
648 /* Common channel scheduled */
649 /* Do the marking for this subframe */
650 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
651 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
652 "rgSCHCmnHdFddChkDlAllow: Possible systemInfo, ueId=%d ",
656 /* Check for actual validation condition 3 */
657 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
658 ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
660 /* No place for HARQ feedback */
661 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
662 "rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
666 /* Mark this sf as DLCNTRL */
667 ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
672 /* If we are here then, subframe at HARQth location can be UL.
673 But check if Guard violation is done */
674 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
675 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
676 /* check for any Common channel info is scheduled */
677 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, (RG_SCH_CMN_HARQ_INTERVAL-1))
678 /* Also get subframe pointer to fetch Common Ch allocation */
679 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
680 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
682 /* Common channel scheduled */
683 /* Do the marking for this subframe */
684 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
685 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
686 "rgSCHCmnHdFddChkDlAllow: (GT) Possible systemInfo, ueId=%d ",
690 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
691 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
693 /* No place for HARQ feedback */
694 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
695 "rgSCHCmnHdFddChkDlAllow: (GT) No place for HARQ feedback,"
696 "ueId=%d ",ueCb->ueId);
701 /* First check for any Common channel info is scheduled */
704 /* All validation done. Safe to for DL */
706 } /* rgSCHCmnHdFddChkDlAllow */
710 /* @brief Decides whether NACK can be sent in a given subrame
714 * Function : rgSCHCmnHdFddChkNackAllow
716 * Invoking Module Processing:
717 * - This shall be invoked by schedulars.
719 * @param[in] RgSchUeCb *ue
726 PUBLIC Void rgSCHCmnHdFddChkNackAllow
730 CmLteTimingInfo timeInfo,
734 PUBLIC Void rgSCHCmnHdFddChkNackAllow(cellCb, ueCb, timeInfo, sndNACK)
737 CmLteTimingInfo timeInfo;
742 CmLteTimingInfo tempTimeInfo;
744 TRC3(rgSCHCmnHdFddChkNackAllow)
746 /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
750 /* Determine SFN and sf index for current subframe.
751 Note: Round function used as example */
752 tempTimeInfo = timeInfo;
753 RGSCH_INCR_SUB_FRAME(tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL);
755 /* Also get subframe pointer to fetch Common Ch allocation */
756 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
758 /* Check is this subframe has any Common Channel info scheduled */
759 if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
761 /* Yes, Cannot send NACK */
762 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
763 "rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
769 /* safe, Send NACK */
770 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
771 "rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
777 } /* rgSCHCmnHdFddChkNackAllow */
782 /* @brief makes final marking for HD-FDD UL allocations
786 * Function : rgSCHCmnHdFddUpdULMark
788 * Invoking Module Processing:
789 * - This shall be invoked by schedulars at the time of UL allocation
794 * @param[in] RgSchCellCb *cellCb
795 * @param[in] RgSchUeCb *ueCb
796 * @param[in] CmLteTimingInfo *timeInfo
797 * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowedi.
798 * Valdity of this pointer is not done in this function.
803 PUBLIC Void rgSCHCmnHdFddUpdULMark
809 PUBLIC Void rgSCHCmnHdFddUpdULMark ( cellCb, ueCb)
817 CmLteTimingInfo timeInfo;
820 TRC3(rgSCHCmnHdFddUpdULMark)
823 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
824 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
825 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset)
828 /* Mark (n + UL_DELTA)th subframe as UL */
830 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
832 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
834 /* Mark (n + UL_DELTA + HARQ_DELTA)th subframe as DL */
835 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
836 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
837 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
839 /* Mark (n + UL_DELTA - HARQ_DELTA)th subframe as DL */
840 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
841 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
842 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_DLDATA)
844 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
847 /* Mark (n + UL_DELTA - 1)th subframe as DL_CNTRL */
848 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
849 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
850 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
852 /* Remove marking for older subframes */
854 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (S16)(ulOffset * -1));
855 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (ulOffset * -1));
856 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_NOSCHD, RG_SCH_HDFDD_INVSFN, sfi);
859 } /* rgSCHCmnHdFddUpdULMark */
864 /* @brief makes final marking for HD-FDD DL allocations
868 * Function : rgSCHCmnHdFddUpdDLMark
870 * Invoking Module Processing:
871 * - This shall be invoked by schedulars at the time of DL allocation
876 * @param[in] RgSchCellCb *cellCb
877 * @param[in] RgSchUeCb *ueCb
878 * @param[in] CmLteTimingInfo *timeInfo
879 * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowed.
880 * Valdity of this pointer is not done in this function
886 PUBLIC Void rgSCHCmnHdFddUpdDLMark
892 PUBLIC Void rgSCHCmnHdFddUpdDLMark (cellCb, ueCb)
900 CmLteTimingInfo timeInfo;
902 TRC3(rgSCHCmnHdFddUpdDLMark)
904 timeInfo = cellCb->crntTime;
905 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
907 /* Mark (n + DL_DELTA)th subframe as DL */
909 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
911 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
913 /* Mark (n + 1)th subframe as DL_CNTRL */
914 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
915 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
916 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
918 /* Mark (n + DL_DELTA + HARQ_DELTA )th subframe as UL */
919 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
920 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
921 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
923 /* Mark (n + DL_DELTA + HARQ_DELTA - 1)th subframe
924 as DL control for Guard period */
925 RG_SCH_HDFDD_GETSFN(sfn, timeInfo,
926 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
927 RG_SCH_HDFDD_GETSFI(sfi, timeInfo,
928 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
929 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
931 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
935 } /* rgSCHCmnHdFddUpdDLMark */
938 /* @brief determines effective SFN
942 * Function : rgSCHHdFddGetSfn
944 * Invoking Module Processing:
945 * Any HD-FDD module can invoke this function.
949 * @param[out] *sfn U32
950 * @param[in] timeInfo timing information subframe of interest
951 * @param[in] offsest Offest with w.r.t which SFN has to be determined
957 PUBLIC Void rgSCHHdFddGetSfn
960 CmLteTimingInfo timeInfo,
964 PUBLIC Void rgSCHHdFddGetSfn (sfn, timeInfo, offset)
966 CmLteTimingInfo timeInfo;
973 TRC3(rgSCHHdFddGetSfn)
974 if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
976 /* Increament to number of times of SFNs that can be possible
978 tempSfn = (timeInfo.sfn +
979 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
980 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
984 if(((S16)(timeInfo.subframe) + offset) < 0)
986 /* If negative, then definitely at least previous SFN */
987 tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
989 /* Now find how many more times we need to decreament */
990 tempSfCount = timeInfo.subframe + offset;
991 RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
995 /* No change in sfn */
996 tempSfn = timeInfo.sfn;
1002 } /* End of rgSCHHdFddGetSfn */
1008 #endif /* __cplusplus */
1010 #endif /* LTEMAC_HDFDD */
1015 /**********************************************************************
1018 **********************************************************************/