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 /* header include files -- defines (.h) */
37 #include "common_def.h"
42 #include "rg_sch_inf.h"
43 #include "rg_sch_err.h"
47 #include "rg_sch_cmn.h"
48 #include "rl_interface.h"
49 #include "rl_common.h"
51 /* header/extern include files (.x) */
52 #include "tfu.x" /* RGU types */
53 #include "lrg.x" /* layer management typedefs for MAC */
54 #include "rgr.x" /* layer management typedefs for MAC */
55 #include "rgm.x" /* layer management typedefs for MAC */
56 #include "rg_sch_inf.x" /* typedefs for Scheduler */
57 #include "rg_sch.x" /* typedefs for Scheduler */
58 #include "rg_sch_cmn.x"
64 #endif /* __cplusplus */
69 * Function : rgSCHHdFddUeCfg
71 * Invoking Module Processing:
72 * - This shall be invoked by SCH_GOM at UE Re/configuration.
75 * - For UE-specific Half Duplex
76 * - Allocate the memory and place the UE in cellCb->hdUeLstCp
77 * - Update subframes information state to defualt
78 * - Update subframes information sfn to defualt
81 * @param[in] RgSchCellCb *cell
82 * @param[in] RgSchUeCb *ue
83 * @param[in] Bool *hdFddEnbl
90 S16 rgSCHHdFddUeCfg(RgSchCellCb *cellCb,RgSchUeCb *ueCb,Bool hdFddEnbl)
94 DU_LOG("\nDEBUG --> SCH : rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
95 ueCb->ueId, hdFddEnbl);
96 if(ueCb->hdFddEnbld == TRUE)
98 if (hdFddEnbl == FALSE)
100 /* Do not allow switch from HD-FDD to FD-FDD configuration */
101 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): HD-FDD to FD-FDD Configuration is not allowed"
102 "CRNTI:%d",ueCb->ueId);
106 /* If already enabled then it can be second reconfiguration */
107 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): HD-FDD already enabled for this UE"
108 "CRNTI:%d",ueCb->ueId);
114 /* Check is SPS enabled for this UE */
115 if(hdFddEnbl == TRUE &&
116 (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
117 ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
119 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
120 "CRNTI:%d",ueCb->ueId);
125 ueCb->hdFddEnbld = hdFddEnbl;
126 if( hdFddEnbl == TRUE)
128 rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
129 sizeof(RgSchUeHdFddCb));
130 if (ueCb->hdFddCb != NULLP)
132 for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
134 ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
135 ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN;
137 /* Add this UE to list maintained in CellCb */
138 /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
142 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
143 "CRNTI:%d",ueCb->ueId);
151 /* @brief Frees Half Duplex related data structures
155 * Function : rgSCHHdFddUeDel
157 * Invoking Module Processing:
158 * - This shall be invoked by SCH_GOM at Ue deletion.
161 * - if Half Duplex is enabled
162 * - if (ueCb->hdFddCb != NULL)
163 * - Remove ue from cellCb->hdUeLstCp;
168 * @param[in] RgSchCellCb *cell
169 * @param[in] RgSchUeCb *ue
175 S16 rgSCHHdFddUeDel(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
178 DU_LOG("\nDEBUG --> SCH : rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
179 ueCb->ueId, ueCb->hdFddEnbld);
184 /* ccpu00117052 - MOD - Passing double pointer
185 for proper NULLP assignment*/
186 rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(ueCb->hdFddCb)),
187 sizeof(RgSchUeHdFddCb));
188 ueCb->hdFddEnbld = FALSE;
192 } /* rgSCHHdFddUeDel */
197 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
202 * Function: rgSCHCmnHdFddPtUlMrk
203 * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission
206 * @param[in] RgSchCellCb *cell
210 Void rgSCHCmnHdFddPtUlMrk(RgSchCellCb *cellCb)
212 uint16_t sfn; /* System Frame Number */
213 uint32_t pti; /* Index into Periodic table */
214 uint16_t sfi; /* Index into HDFDD state table */
223 CmLteTimingInfo timeInfo;
224 RgSchUePCqiCb *cqiCb = NULLP;
225 RgSchUePCqiCb *riCb = NULLP;
228 timeInfo = cellCb->crntTime;
230 /* Determine indexes */
231 pti = RG_SCH_HDFDD_GETPTI(timeInfo);
232 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_DELTA);
233 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_DELTA);
235 /* Get PT entries for */
236 cqiLst = &cellCb->pCqiSrsSrLst[pti].cqiLst;
237 srsLst = &cellCb->pCqiSrsSrLst[pti].srsLst;
238 srLst = &cellCb->pCqiSrsSrLst[pti].srLst;
239 riLst = &cellCb->pCqiSrsSrLst[pti].riLst;
241 /* Get first node in each list */
242 CM_LLIST_FIRST_NODE(cqiLst, cqiNode);
243 CM_LLIST_FIRST_NODE(srsLst, srsNode);
244 CM_LLIST_FIRST_NODE(riLst, riNode);
245 CM_LLIST_FIRST_NODE(srLst, srNode);
247 /* Mark corresponding the subframe as uplink control */
248 while ((NULLP != cqiNode ) &&
249 (NULLP != srsNode ) &&
250 (NULLP != srNode ) &&
253 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
254 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
255 RG_SCH_HDFDD_UL, sfn, sfi);
256 /* SRS Transmission instances */
257 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srsNode->node,
258 RG_SCH_HDFDD_UL, sfn, sfi);
259 /* SR Transmission instances */
260 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srNode->node,
261 RG_SCH_HDFDD_UL, sfn, sfi);
262 /* RI Transmission instances */
263 riCb = (RgSchUePCqiCb *)(riNode->node);
264 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
265 RG_SCH_HDFDD_UL, sfn, sfi);
267 /* Get next UeCb for all lists */
268 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
269 CM_LLIST_NEXT_NODE(srsLst, srsNode);
270 CM_LLIST_NEXT_NODE(srLst, srNode);
271 CM_LLIST_NEXT_NODE(riLst, riNode);
274 while ( NULLP != cqiNode)
276 /* CQI/PMI Transmission instances */
277 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
278 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
279 RG_SCH_HDFDD_UL, sfn, sfi);
280 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
282 while( NULLP != srsNode)
284 /* SRS Transmission instances */
285 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srsNode->node),
286 RG_SCH_HDFDD_UL, sfn, sfi);
287 CM_LLIST_NEXT_NODE(srsLst, srsNode);
289 while( NULLP != srNode)
291 /* SR Transmission instances */
292 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srNode->node),
293 RG_SCH_HDFDD_UL, sfn, sfi);
294 CM_LLIST_NEXT_NODE(srLst, srNode);
296 while( NULLP != riNode)
298 /* RI Transmission instances */
299 riCb = (RgSchUePCqiCb *)(riNode->node);
300 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
301 RG_SCH_HDFDD_UL, sfn, sfi);
302 CM_LLIST_NEXT_NODE(riLst, riNode);
306 } /* rgSCHCmnHdFddPtUlMrk */
307 #endif /* ifdef TFU_UPGRADE */
311 /* @brief Decides whether UE can be allowed for DL in given subframe
315 * Function : rgSCHCmnHdFddChkUlAllow
317 * Invoking Module Processing:
318 * - This shall be invoked by schedulars before allocating UL grants .
321 * - if Half Duplex is enabled
322 * - If ue->sf[reqsf].state is "DONWLINK"
323 * set alloweUlSch=FALSE
325 * set alloweUlSch=TRUE
326 * This function Marking for BCCH/PCCH occasions is also done
328 * @param[in] RgSchCellCb *cell
329 * @param[in] RgSchUeCb *ue
334 Void rgSCHCmnHdFddChkUlAllow(RgSchCellCb *cellCb,RgSchUeCb *ueCb,uint8_t *allow)
338 CmLteTimingInfo timeInfo;
339 RgSchDlSf *sf = NULLP; /* Dl subframe info */
342 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
346 timeInfo = cellCb->crntTime;
348 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
349 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
350 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset);
352 /* Set default value */
355 /* Validate condition 1 */
356 /* For (curretn time + DL_DELTA)th sf */
358 /* Also get subframe pointer to fetch Common Ch allocation */
359 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
362 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
364 /* Validate condition 2 */
365 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
367 /* Common channel scheduled */
368 /* Mark the BCCH/PCCH occasion */
369 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
370 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
373 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
374 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA ||
375 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLCNTRL))
377 /* Downlink scheduled */
379 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
384 /* Validate condition 3 */
385 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf
386 - i.e. next HARQ Feedback occasion */
387 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
388 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
389 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
390 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
392 /* No place for HARQ feedback */
394 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
399 /* Validate condition 4 */
400 /* For (curretn time + DL_DELTA - HRQ_DELTA)th sf
401 - i.e. previous HARQ Feedback occasion */
402 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
403 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
404 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
405 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
408 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
413 /* Validate condition 5 */
414 /* For (curretn time + DL_DELTA - 1)th sf -i.e. Guard time */
415 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
416 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
417 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
418 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA))
420 /* This subframe may be a switching gaurd time */
422 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
427 /* Adition guard time rule check: Above check is only for PDSCH, lets check
428 is there is any BCCH/PCCH data scheduled */
429 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo,
430 (ulOffset - RG_SCH_HDFDD_GRDTIM_DUR));
431 /* Also get subframe pointer to fetch Common Ch allocation */
432 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
433 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
435 /* Common channel scheduled */
436 /* Mark the BCCH/PCCH occasion */
437 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
439 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
445 /* All validation done. Safe to for UL */
448 } /* rgSCHCmnHdFddChkUlAllow */
451 /* @brief Decides whether UE can be allowed for UL in given subframe
455 * Function : rgSCHCmnHdFddChkDlAllow
457 * Invoking Module Processing:
458 * - This shall be invoked by schedulars before allocating for DL.
461 * Condition 1: subframe n + DL_DELTA should not be uplink
462 * Condition 2: subframe n+ DL_DELTA + 1 should meet guard time
463 * creation rule. For more
464 * information refer to section "2.25.7.1 Guard time
466 * Condition 3: subframe n + DL_DELTA + HRQ_DELTA should not be
467 * downlink so that downlink data (HARQ Feedback)
468 * can be received in next 4 subframe. {n + 7} Above
470 * be validated by taking SFN number into consideration.
471 * if all conditions are met then *allow is set to TRUE or lese to
473 * if hd-fdd is not anabled for this UE, then *allow is always TRUE.
476 * @param[in] RgSchCellCb *cellCb
477 * @param[in] RgSchUeCb *ueCb
478 * @param[in] CmLteTimingInfo *timeInfo
479 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
480 * Valdity of this pointer is not done in this function
483 Void rgSCHCmnHdFddChkDlAllow
487 Bool *allow /* Valdity of this pointer is not done in this function */
492 RgSchDlSf *sf = NULLP; /* Dl subframe info */
493 CmLteTimingInfo timeInfo;
494 CmLteTimingInfo tempTimeInfo;
498 timeInfo = cellCb->crntTime;
499 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
501 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
503 /* Also get subframe pointer to fetch Common Ch allocation */
504 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
506 /* Validate condition 1 */
507 /* For (curretn time + DL_DELTA)th sf */
509 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
511 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
512 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
514 /* Uplink scheduled */
515 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
520 /* It is not validation, but BCCH/PCCH marking is done here */
521 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
523 /* Common channel scheduled */
524 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
527 /* Validate condition 2 */
528 /* For (curretn time + DL_DELTA + 1)th sf -i.e. Guard time */
529 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
530 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
531 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
532 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
534 /* This subframe may be a switching guard time */
535 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: Guard time rule not met, ueId=%d ",
541 /* Validate condition 3 */
542 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
545 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
546 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
548 /* First check for any Common channel info is scheduled */
549 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL)
550 /* Also get subframe pointer to fetch Common Ch allocation */
551 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
552 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
554 /* Common channel scheduled */
555 /* Do the marking for this subframe */
556 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
557 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkDlAllow: Possible systemInfo, ueId=%d ",
561 /* Check for actual validation condition 3 */
562 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
563 ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
565 /* No place for HARQ feedback */
566 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
570 /* Mark this sf as DLCNTRL */
571 ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
576 /* If we are here then, subframe at HARQth location can be UL.
577 But check if Guard violation is done */
578 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
579 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
580 /* check for any Common channel info is scheduled */
581 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, (RG_SCH_CMN_HARQ_INTERVAL-1))
582 /* Also get subframe pointer to fetch Common Ch allocation */
583 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
584 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
586 /* Common channel scheduled */
587 /* Do the marking for this subframe */
588 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
589 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkDlAllow: (GT) Possible systemInfo, ueId=%d ",
593 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
594 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
596 /* No place for HARQ feedback */
597 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: (GT) No place for HARQ feedback,"
598 "ueId=%d ",ueCb->ueId);
603 /* First check for any Common channel info is scheduled */
606 /* All validation done. Safe to for DL */
608 } /* rgSCHCmnHdFddChkDlAllow */
612 /* @brief Decides whether NACK can be sent in a given subrame
616 * Function : rgSCHCmnHdFddChkNackAllow
618 * Invoking Module Processing:
619 * - This shall be invoked by schedulars.
621 * @param[in] RgSchUeCb *ue
627 Void rgSCHCmnHdFddChkNackAllow(RgSchCellCb *cellCb,RgSchUeCb *ueCb,CmLteTimingInfo timeInfo,Bool *sndNACK)
630 CmLteTimingInfo tempTimeInfo;
632 /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
636 /* Determine SFN and sf index for current subframe.
637 Note: Round function used as example */
638 tempTimeInfo = timeInfo;
639 RGSCH_INCR_SUB_FRAME(tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL);
641 /* Also get subframe pointer to fetch Common Ch allocation */
642 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
644 /* Check is this subframe has any Common Channel info scheduled */
645 if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
647 /* Yes, Cannot send NACK */
648 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
654 /* safe, Send NACK */
655 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
661 } /* rgSCHCmnHdFddChkNackAllow */
666 /* @brief makes final marking for HD-FDD UL allocations
670 * Function : rgSCHCmnHdFddUpdULMark
672 * Invoking Module Processing:
673 * - This shall be invoked by schedulars at the time of UL allocation
678 * @param[in] RgSchCellCb *cellCb
679 * @param[in] RgSchUeCb *ueCb
680 * @param[in] CmLteTimingInfo *timeInfo
681 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
682 * Valdity of this pointer is not done in this function.
686 Void rgSCHCmnHdFddUpdULMark(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
691 CmLteTimingInfo timeInfo;
694 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
695 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
696 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset)
699 /* Mark (n + UL_DELTA)th subframe as UL */
701 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
703 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
705 /* Mark (n + UL_DELTA + HARQ_DELTA)th subframe as DL */
706 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
707 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
708 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
710 /* Mark (n + UL_DELTA - HARQ_DELTA)th subframe as DL */
711 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
712 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
713 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_DLDATA)
715 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
718 /* Mark (n + UL_DELTA - 1)th subframe as DL_CNTRL */
719 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
720 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
721 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
723 /* Remove marking for older subframes */
725 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (S16)(ulOffset * -1));
726 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (ulOffset * -1));
727 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_NOSCHD, RG_SCH_HDFDD_INVSFN, sfi);
730 } /* rgSCHCmnHdFddUpdULMark */
735 /* @brief makes final marking for HD-FDD DL allocations
739 * Function : rgSCHCmnHdFddUpdDLMark
741 * Invoking Module Processing:
742 * - This shall be invoked by schedulars at the time of DL allocation
747 * @param[in] RgSchCellCb *cellCb
748 * @param[in] RgSchUeCb *ueCb
749 * @param[in] CmLteTimingInfo *timeInfo
750 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowed.
751 * Valdity of this pointer is not done in this function
756 Void rgSCHCmnHdFddUpdDLMark(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
761 CmLteTimingInfo timeInfo;
763 timeInfo = cellCb->crntTime;
764 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
766 /* Mark (n + DL_DELTA)th subframe as DL */
768 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
770 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
772 /* Mark (n + 1)th subframe as DL_CNTRL */
773 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
774 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
775 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
777 /* Mark (n + DL_DELTA + HARQ_DELTA )th subframe as UL */
778 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
779 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
780 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
782 /* Mark (n + DL_DELTA + HARQ_DELTA - 1)th subframe
783 as DL control for Guard period */
784 RG_SCH_HDFDD_GETSFN(sfn, timeInfo,
785 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
786 RG_SCH_HDFDD_GETSFI(sfi, timeInfo,
787 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
788 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
790 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
794 } /* rgSCHCmnHdFddUpdDLMark */
797 /* @brief determines effective SFN
801 * Function : rgSCHHdFddGetSfn
803 * Invoking Module Processing:
804 * Any HD-FDD module can invoke this function.
808 * @param[out] *sfn uint32_t
809 * @param[in] timeInfo timing information subframe of interest
810 * @param[in] offsest Offest with w.r.t which SFN has to be determined
815 Void rgSCHHdFddGetSfn(uint16_t *sfn,CmLteTimingInfo timeInfo,S16 offset)
820 if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
822 /* Increament to number of times of SFNs that can be possible
824 tempSfn = (timeInfo.sfn +
825 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
826 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
830 if(((S16)(timeInfo.subframe) + offset) < 0)
832 /* If negative, then definitely at least previous SFN */
833 tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
835 /* Now find how many more times we need to decreament */
836 tempSfCount = timeInfo.subframe + offset;
837 RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
841 /* No change in sfn */
842 tempSfn = timeInfo.sfn;
848 } /* End of rgSCHHdFddGetSfn */
854 #endif /* __cplusplus */
856 #endif /* LTEMAC_HDFDD */
861 /**********************************************************************
864 **********************************************************************/