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
103 S16 rgSCHHdFddUeCfg (cellCb, ueCb, hdFddEnbl)
111 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
112 "rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
113 ueCb->ueId, hdFddEnbl);
114 if(ueCb->hdFddEnbld == TRUE)
116 if (hdFddEnbl == FALSE)
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);
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);
134 /* Check is SPS enabled for this UE */
135 if(hdFddEnbl == TRUE &&
136 (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
137 ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
139 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
140 "rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
141 "CRNTI:%d",ueCb->ueId);
146 ueCb->hdFddEnbld = hdFddEnbl;
147 if( hdFddEnbl == TRUE)
149 rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
150 sizeof(RgSchUeHdFddCb));
151 if (ueCb->hdFddCb != NULLP)
153 for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
155 ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
156 ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN;
158 /* Add this UE to list maintained in CellCb */
159 /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
163 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
164 "rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
165 "CRNTI:%d",ueCb->ueId);
173 /* @brief Frees Half Duplex related data structures
177 * Function : rgSCHHdFddUeDel
179 * Invoking Module Processing:
180 * - This shall be invoked by SCH_GOM at Ue deletion.
183 * - if Half Duplex is enabled
184 * - if (ueCb->hdFddCb != NULL)
185 * - Remove ue from cellCb->hdUeLstCp;
190 * @param[in] RgSchCellCb *cell
191 * @param[in] RgSchUeCb *ue
204 S16 rgSCHHdFddUeDel(cellCb, ueCb)
210 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
211 " rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
212 ueCb->ueId, ueCb->hdFddEnbld);
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;
225 } /* rgSCHHdFddUeDel */
230 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
235 * Function: rgSCHCmnHdFddPtUlMrk
236 * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission
239 * @param[in] RgSchCellCb *cell
244 Void rgSCHCmnHdFddPtUlMrk
249 Void rgSCHCmnHdFddPtUlMrk (cellCb)
253 U16 sfn; /* System Frame Number */
254 U32 pti; /* Index into Periodic table */
255 U16 sfi; /* Index into HDFDD state table */
264 CmLteTimingInfo timeInfo;
265 RgSchUePCqiCb *cqiCb = NULLP;
266 RgSchUePCqiCb *riCb = NULLP;
269 timeInfo = cellCb->crntTime;
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);
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;
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);
288 /* Mark corresponding the subframe as uplink control */
289 while ((NULLP != cqiNode ) &&
290 (NULLP != srsNode ) &&
291 (NULLP != srNode ) &&
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);
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);
315 while ( NULLP != cqiNode)
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);
323 while( NULLP != srsNode)
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);
330 while( NULLP != srNode)
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);
337 while( NULLP != riNode)
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);
347 } /* rgSCHCmnHdFddPtUlMrk */
348 #endif /* ifdef TFU_UPGRADE */
352 /* @brief Decides whether UE can be allowed for DL in given subframe
356 * Function : rgSCHCmnHdFddChkUlAllow
358 * Invoking Module Processing:
359 * - This shall be invoked by schedulars before allocating UL grants .
362 * - if Half Duplex is enabled
363 * - If ue->sf[reqsf].state is "DONWLINK"
364 * set alloweUlSch=FALSE
366 * set alloweUlSch=TRUE
367 * This function Marking for BCCH/PCCH occasions is also done
369 * @param[in] RgSchCellCb *cell
370 * @param[in] RgSchUeCb *ue
376 Void rgSCHCmnHdFddChkUlAllow
383 Void rgSCHCmnHdFddChkUlAllow ( cellCb, ueCb, allow)
391 CmLteTimingInfo timeInfo;
392 RgSchDlSf *sf = NULLP; /* Dl subframe info */
395 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
396 " rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
400 timeInfo = cellCb->crntTime;
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);
406 /* Set default value */
409 /* Validate condition 1 */
410 /* For (curretn time + DL_DELTA)th sf */
412 /* Also get subframe pointer to fetch Common Ch allocation */
413 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
416 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
418 /* Validate condition 2 */
419 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
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 ",
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))
432 /* Downlink scheduled */
434 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
435 "rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
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)
448 /* No place for HARQ feedback */
450 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
451 "rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
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)
465 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
466 " rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
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))
478 /* This subframe may be a switching gaurd time */
480 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
481 " rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
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))
494 /* Common channel scheduled */
495 /* Mark the BCCH/PCCH occasion */
496 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
498 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
499 "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
505 /* All validation done. Safe to for UL */
508 } /* rgSCHCmnHdFddChkUlAllow */
511 /* @brief Decides whether UE can be allowed for UL in given subframe
515 * Function : rgSCHCmnHdFddChkDlAllow
517 * Invoking Module Processing:
518 * - This shall be invoked by schedulars before allocating for DL.
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
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
530 * be validated by taking SFN number into consideration.
531 * if all conditions are met then *allow is set to TRUE or lese to
533 * if hd-fdd is not anabled for this UE, then *allow is always TRUE.
536 * @param[in] RgSchCellCb *cellCb
537 * @param[in] RgSchUeCb *ueCb
538 * @param[in] CmLteTimingInfo *timeInfo
539 * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowedi.
540 * Valdity of this pointer is not done in this function
544 Void rgSCHCmnHdFddChkDlAllow
548 Bool *allow /* Valdity of this pointer is not done in this function */
551 Void rgSCHCmnHdFddChkDlAllow ( cellCb, ueCb, allow)
554 Bool *allow; /* Valdity of this pointer is not done in this function */
559 RgSchDlSf *sf = NULLP; /* Dl subframe info */
560 CmLteTimingInfo timeInfo;
561 CmLteTimingInfo tempTimeInfo;
565 timeInfo = cellCb->crntTime;
566 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
568 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
569 "rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
571 /* Also get subframe pointer to fetch Common Ch allocation */
572 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
574 /* Validate condition 1 */
575 /* For (curretn time + DL_DELTA)th sf */
577 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
579 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
580 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
582 /* Uplink scheduled */
583 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
584 "rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
589 /* It is not validation, but BCCH/PCCH marking is done here */
590 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
592 /* Common channel scheduled */
593 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
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))
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 ",
611 /* Validate condition 3 */
612 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
615 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
616 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
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))
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 ",
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)
636 /* No place for HARQ feedback */
637 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
638 "rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
642 /* Mark this sf as DLCNTRL */
643 ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
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))
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 ",
666 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
667 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
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);
677 /* First check for any Common channel info is scheduled */
680 /* All validation done. Safe to for DL */
682 } /* rgSCHCmnHdFddChkDlAllow */
686 /* @brief Decides whether NACK can be sent in a given subrame
690 * Function : rgSCHCmnHdFddChkNackAllow
692 * Invoking Module Processing:
693 * - This shall be invoked by schedulars.
695 * @param[in] RgSchUeCb *ue
702 Void rgSCHCmnHdFddChkNackAllow
706 CmLteTimingInfo timeInfo,
710 Void rgSCHCmnHdFddChkNackAllow(cellCb, ueCb, timeInfo, sndNACK)
713 CmLteTimingInfo timeInfo;
718 CmLteTimingInfo tempTimeInfo;
720 /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
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);
729 /* Also get subframe pointer to fetch Common Ch allocation */
730 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
732 /* Check is this subframe has any Common Channel info scheduled */
733 if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
735 /* Yes, Cannot send NACK */
736 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
737 "rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
743 /* safe, Send NACK */
744 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
745 "rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
751 } /* rgSCHCmnHdFddChkNackAllow */
756 /* @brief makes final marking for HD-FDD UL allocations
760 * Function : rgSCHCmnHdFddUpdULMark
762 * Invoking Module Processing:
763 * - This shall be invoked by schedulars at the time of UL allocation
768 * @param[in] RgSchCellCb *cellCb
769 * @param[in] RgSchUeCb *ueCb
770 * @param[in] CmLteTimingInfo *timeInfo
771 * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowedi.
772 * Valdity of this pointer is not done in this function.
777 Void rgSCHCmnHdFddUpdULMark
783 Void rgSCHCmnHdFddUpdULMark ( cellCb, ueCb)
791 CmLteTimingInfo timeInfo;
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)
799 /* Mark (n + UL_DELTA)th subframe as UL */
801 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
803 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
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);
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)
815 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
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);
823 /* Remove marking for older subframes */
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);
830 } /* rgSCHCmnHdFddUpdULMark */
835 /* @brief makes final marking for HD-FDD DL allocations
839 * Function : rgSCHCmnHdFddUpdDLMark
841 * Invoking Module Processing:
842 * - This shall be invoked by schedulars at the time of DL allocation
847 * @param[in] RgSchCellCb *cellCb
848 * @param[in] RgSchUeCb *ueCb
849 * @param[in] CmLteTimingInfo *timeInfo
850 * @param[out] U8 *allow -- TRUE is allowed or FALSE if no allowed.
851 * Valdity of this pointer is not done in this function
857 Void rgSCHCmnHdFddUpdDLMark
863 Void rgSCHCmnHdFddUpdDLMark (cellCb, ueCb)
871 CmLteTimingInfo timeInfo;
873 timeInfo = cellCb->crntTime;
874 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
876 /* Mark (n + DL_DELTA)th subframe as DL */
878 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
880 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
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);
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);
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)
900 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
904 } /* rgSCHCmnHdFddUpdDLMark */
907 /* @brief determines effective SFN
911 * Function : rgSCHHdFddGetSfn
913 * Invoking Module Processing:
914 * Any HD-FDD module can invoke this function.
918 * @param[out] *sfn U32
919 * @param[in] timeInfo timing information subframe of interest
920 * @param[in] offsest Offest with w.r.t which SFN has to be determined
926 Void rgSCHHdFddGetSfn
929 CmLteTimingInfo timeInfo,
933 Void rgSCHHdFddGetSfn (sfn, timeInfo, offset)
935 CmLteTimingInfo timeInfo;
942 if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
944 /* Increament to number of times of SFNs that can be possible
946 tempSfn = (timeInfo.sfn +
947 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
948 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
952 if(((S16)(timeInfo.subframe) + offset) < 0)
954 /* If negative, then definitely at least previous SFN */
955 tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
957 /* Now find how many more times we need to decreament */
958 tempSfCount = timeInfo.subframe + offset;
959 RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
963 /* No change in sfn */
964 tempSfn = timeInfo.sfn;
970 } /* End of rgSCHHdFddGetSfn */
976 #endif /* __cplusplus */
978 #endif /* LTEMAC_HDFDD */
983 /**********************************************************************
986 **********************************************************************/