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 "common_def.h"
47 #include "rg_sch_inf.h"
48 #include "rg_sch_err.h"
52 #include "rg_sch_cmn.h"
53 #include "rl_interface.h"
54 #include "rl_common.h"
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"
69 #endif /* __cplusplus */
74 * Function : rgSCHHdFddUeCfg
76 * Invoking Module Processing:
77 * - This shall be invoked by SCH_GOM at UE Re/configuration.
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
86 * @param[in] RgSchCellCb *cell
87 * @param[in] RgSchUeCb *ue
88 * @param[in] Bool *hdFddEnbl
96 PUBLIC S16 rgSCHHdFddUeCfg
103 PUBLIC S16 rgSCHHdFddUeCfg (cellCb, ueCb, hdFddEnbl)
110 TRC3(rgSCHHdFddUeCfg)
112 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
113 "rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
114 ueCb->ueId, hdFddEnbl);
115 if(ueCb->hdFddEnbld == TRUE)
117 if (hdFddEnbl == FALSE)
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);
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);
135 /* Check is SPS enabled for this UE */
136 if(hdFddEnbl == TRUE &&
137 (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
138 ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
140 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
141 "rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
142 "CRNTI:%d",ueCb->ueId);
147 ueCb->hdFddEnbld = hdFddEnbl;
148 if( hdFddEnbl == TRUE)
150 rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
151 sizeof(RgSchUeHdFddCb));
152 if (ueCb->hdFddCb != NULLP)
154 for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
156 ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
157 ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN;
159 /* Add this UE to list maintained in CellCb */
160 /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
164 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
165 "rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
166 "CRNTI:%d",ueCb->ueId);
174 /* @brief Frees Half Duplex related data structures
178 * Function : rgSCHHdFddUeDel
180 * Invoking Module Processing:
181 * - This shall be invoked by SCH_GOM at Ue deletion.
184 * - if Half Duplex is enabled
185 * - if (ueCb->hdFddCb != NULL)
186 * - Remove ue from cellCb->hdUeLstCp;
191 * @param[in] RgSchCellCb *cell
192 * @param[in] RgSchUeCb *ue
199 PUBLIC S16 rgSCHHdFddUeDel
205 PUBLIC S16 rgSCHHdFddUeDel(cellCb, ueCb)
210 TRC3(rgSCHHdFddUeDel)
212 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
213 " rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
214 ueCb->ueId, ueCb->hdFddEnbld);
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;
227 } /* rgSCHHdFddUeDel */
232 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
237 * Function: rgSCHCmnHdFddPtUlMrk
238 * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission
241 * @param[in] RgSchCellCb *cell
246 PUBLIC Void rgSCHCmnHdFddPtUlMrk
251 PUBLIC Void rgSCHCmnHdFddPtUlMrk (cellCb)
255 U16 sfn; /* System Frame Number */
256 U32 pti; /* Index into Periodic table */
257 U16 sfi; /* Index into HDFDD state table */
266 CmLteTimingInfo timeInfo;
267 RgSchUePCqiCb *cqiCb = NULLP;
268 RgSchUePCqiCb *riCb = NULLP;
270 TRC3(rgSCHCmnHdFddPtUlMrk)
272 timeInfo = cellCb->crntTime;
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);
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;
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);
291 /* Mark corresponding the subframe as uplink control */
292 while ((NULLP != cqiNode ) &&
293 (NULLP != srsNode ) &&
294 (NULLP != srNode ) &&
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);
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);
318 while ( NULLP != cqiNode)
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);
326 while( NULLP != srsNode)
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);
333 while( NULLP != srNode)
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);
340 while( NULLP != riNode)
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);
350 } /* rgSCHCmnHdFddPtUlMrk */
351 #endif /* ifdef TFU_UPGRADE */
355 /* @brief Decides whether UE can be allowed for DL in given subframe
359 * Function : rgSCHCmnHdFddChkUlAllow
361 * Invoking Module Processing:
362 * - This shall be invoked by schedulars before allocating UL grants .
365 * - if Half Duplex is enabled
366 * - If ue->sf[reqsf].state is "DONWLINK"
367 * set alloweUlSch=FALSE
369 * set alloweUlSch=TRUE
370 * This function Marking for BCCH/PCCH occasions is also done
372 * @param[in] RgSchCellCb *cell
373 * @param[in] RgSchUeCb *ue
379 PUBLIC Void rgSCHCmnHdFddChkUlAllow
386 PUBLIC Void rgSCHCmnHdFddChkUlAllow ( cellCb, ueCb, allow)
394 CmLteTimingInfo timeInfo;
395 RgSchDlSf *sf = NULLP; /* Dl subframe info */
398 TRC3(rgSCHCmnHdFddChkUlAllow)
400 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
401 " rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
405 timeInfo = cellCb->crntTime;
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);
411 /* Set default value */
414 /* Validate condition 1 */
415 /* For (curretn time + DL_DELTA)th sf */
417 /* Also get subframe pointer to fetch Common Ch allocation */
418 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
421 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
423 /* Validate condition 2 */
424 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
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 ",
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))
437 /* Downlink scheduled */
439 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
440 "rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
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)
453 /* No place for HARQ feedback */
455 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
456 "rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
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)
470 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
471 " rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
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))
483 /* This subframe may be a switching gaurd time */
485 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
486 " rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
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))
499 /* Common channel scheduled */
500 /* Mark the BCCH/PCCH occasion */
501 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
503 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
504 "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
510 /* All validation done. Safe to for UL */
513 } /* rgSCHCmnHdFddChkUlAllow */
516 /* @brief Decides whether UE can be allowed for UL in given subframe
520 * Function : rgSCHCmnHdFddChkDlAllow
522 * Invoking Module Processing:
523 * - This shall be invoked by schedulars before allocating for DL.
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
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
535 * be validated by taking SFN number into consideration.
536 * if all conditions are met then *allow is set to TRUE or lese to
538 * if hd-fdd is not anabled for this UE, then *allow is always TRUE.
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
549 PUBLIC Void rgSCHCmnHdFddChkDlAllow
553 Bool *allow /* Valdity of this pointer is not done in this function */
556 PUBLIC Void rgSCHCmnHdFddChkDlAllow ( cellCb, ueCb, allow)
559 Bool *allow; /* Valdity of this pointer is not done in this function */
564 RgSchDlSf *sf = NULLP; /* Dl subframe info */
565 CmLteTimingInfo timeInfo;
566 CmLteTimingInfo tempTimeInfo;
568 TRC3(rgSCHCmnHdFddChkDlAllow)
572 timeInfo = cellCb->crntTime;
573 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
575 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
576 "rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
578 /* Also get subframe pointer to fetch Common Ch allocation */
579 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
581 /* Validate condition 1 */
582 /* For (curretn time + DL_DELTA)th sf */
584 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
586 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
587 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
589 /* Uplink scheduled */
590 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
591 "rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
596 /* It is not validation, but BCCH/PCCH marking is done here */
597 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
599 /* Common channel scheduled */
600 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
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))
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 ",
618 /* Validate condition 3 */
619 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
622 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
623 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
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))
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 ",
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)
643 /* No place for HARQ feedback */
644 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
645 "rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
649 /* Mark this sf as DLCNTRL */
650 ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
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))
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 ",
673 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
674 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
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);
684 /* First check for any Common channel info is scheduled */
687 /* All validation done. Safe to for DL */
689 } /* rgSCHCmnHdFddChkDlAllow */
693 /* @brief Decides whether NACK can be sent in a given subrame
697 * Function : rgSCHCmnHdFddChkNackAllow
699 * Invoking Module Processing:
700 * - This shall be invoked by schedulars.
702 * @param[in] RgSchUeCb *ue
709 PUBLIC Void rgSCHCmnHdFddChkNackAllow
713 CmLteTimingInfo timeInfo,
717 PUBLIC Void rgSCHCmnHdFddChkNackAllow(cellCb, ueCb, timeInfo, sndNACK)
720 CmLteTimingInfo timeInfo;
725 CmLteTimingInfo tempTimeInfo;
727 TRC3(rgSCHCmnHdFddChkNackAllow)
729 /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
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);
738 /* Also get subframe pointer to fetch Common Ch allocation */
739 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
741 /* Check is this subframe has any Common Channel info scheduled */
742 if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
744 /* Yes, Cannot send NACK */
745 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
746 "rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
752 /* safe, Send NACK */
753 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
754 "rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
760 } /* rgSCHCmnHdFddChkNackAllow */
765 /* @brief makes final marking for HD-FDD UL allocations
769 * Function : rgSCHCmnHdFddUpdULMark
771 * Invoking Module Processing:
772 * - This shall be invoked by schedulars at the time of UL allocation
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.
786 PUBLIC Void rgSCHCmnHdFddUpdULMark
792 PUBLIC Void rgSCHCmnHdFddUpdULMark ( cellCb, ueCb)
800 CmLteTimingInfo timeInfo;
803 TRC3(rgSCHCmnHdFddUpdULMark)
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)
811 /* Mark (n + UL_DELTA)th subframe as UL */
813 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
815 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
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);
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)
827 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
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);
835 /* Remove marking for older subframes */
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);
842 } /* rgSCHCmnHdFddUpdULMark */
847 /* @brief makes final marking for HD-FDD DL allocations
851 * Function : rgSCHCmnHdFddUpdDLMark
853 * Invoking Module Processing:
854 * - This shall be invoked by schedulars at the time of DL allocation
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
869 PUBLIC Void rgSCHCmnHdFddUpdDLMark
875 PUBLIC Void rgSCHCmnHdFddUpdDLMark (cellCb, ueCb)
883 CmLteTimingInfo timeInfo;
885 TRC3(rgSCHCmnHdFddUpdDLMark)
887 timeInfo = cellCb->crntTime;
888 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
890 /* Mark (n + DL_DELTA)th subframe as DL */
892 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
894 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
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);
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);
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)
914 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
918 } /* rgSCHCmnHdFddUpdDLMark */
921 /* @brief determines effective SFN
925 * Function : rgSCHHdFddGetSfn
927 * Invoking Module Processing:
928 * Any HD-FDD module can invoke this function.
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
940 PUBLIC Void rgSCHHdFddGetSfn
943 CmLteTimingInfo timeInfo,
947 PUBLIC Void rgSCHHdFddGetSfn (sfn, timeInfo, offset)
949 CmLteTimingInfo timeInfo;
956 TRC3(rgSCHHdFddGetSfn)
957 if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
959 /* Increament to number of times of SFNs that can be possible
961 tempSfn = (timeInfo.sfn +
962 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
963 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
967 if(((S16)(timeInfo.subframe) + offset) < 0)
969 /* If negative, then definitely at least previous SFN */
970 tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
972 /* Now find how many more times we need to decreament */
973 tempSfCount = timeInfo.subframe + offset;
974 RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
978 /* No change in sfn */
979 tempSfn = timeInfo.sfn;
985 } /* End of rgSCHHdFddGetSfn */
991 #endif /* __cplusplus */
993 #endif /* LTEMAC_HDFDD */
998 /**********************************************************************
1001 **********************************************************************/