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"
49 /* header/extern include files (.x) */
50 #include "tfu.x" /* RGU types */
51 #include "lrg.x" /* layer management typedefs for MAC */
52 #include "rgr.x" /* layer management typedefs for MAC */
53 #include "rgm.x" /* layer management typedefs for MAC */
54 #include "rg_sch_inf.x" /* typedefs for Scheduler */
55 #include "rg_sch.x" /* typedefs for Scheduler */
56 #include "rg_sch_cmn.x"
62 #endif /* __cplusplus */
67 * Function : rgSCHHdFddUeCfg
69 * Invoking Module Processing:
70 * - This shall be invoked by SCH_GOM at UE Re/configuration.
73 * - For UE-specific Half Duplex
74 * - Allocate the memory and place the UE in cellCb->hdUeLstCp
75 * - Update subframes information state to defualt
76 * - Update subframes information sfn to defualt
79 * @param[in] RgSchCellCb *cell
80 * @param[in] RgSchUeCb *ue
81 * @param[in] Bool *hdFddEnbl
88 S16 rgSCHHdFddUeCfg(RgSchCellCb *cellCb,RgSchUeCb *ueCb,Bool hdFddEnbl)
92 DU_LOG("\nDEBUG --> SCH : rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
93 ueCb->ueId, hdFddEnbl);
94 if(ueCb->hdFddEnbld == TRUE)
96 if (hdFddEnbl == FALSE)
98 /* Do not allow switch from HD-FDD to FD-FDD configuration */
99 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): HD-FDD to FD-FDD Configuration is not allowed"
100 "CRNTI:%d",ueCb->ueId);
104 /* If already enabled then it can be second reconfiguration */
105 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): HD-FDD already enabled for this UE"
106 "CRNTI:%d",ueCb->ueId);
112 /* Check is SPS enabled for this UE */
113 if(hdFddEnbl == TRUE &&
114 (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
115 ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
117 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
118 "CRNTI:%d",ueCb->ueId);
123 ueCb->hdFddEnbld = hdFddEnbl;
124 if( hdFddEnbl == TRUE)
126 rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
127 sizeof(RgSchUeHdFddCb));
128 if (ueCb->hdFddCb != NULLP)
130 for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
132 ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
133 ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN;
135 /* Add this UE to list maintained in CellCb */
136 /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
140 DU_LOG("\nERROR --> SCH : rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
141 "CRNTI:%d",ueCb->ueId);
149 /* @brief Frees Half Duplex related data structures
153 * Function : rgSCHHdFddUeDel
155 * Invoking Module Processing:
156 * - This shall be invoked by SCH_GOM at Ue deletion.
159 * - if Half Duplex is enabled
160 * - if (ueCb->hdFddCb != NULL)
161 * - Remove ue from cellCb->hdUeLstCp;
166 * @param[in] RgSchCellCb *cell
167 * @param[in] RgSchUeCb *ue
173 S16 rgSCHHdFddUeDel(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
176 DU_LOG("\nDEBUG --> SCH : rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
177 ueCb->ueId, ueCb->hdFddEnbld);
182 /* ccpu00117052 - MOD - Passing double pointer
183 for proper NULLP assignment*/
184 rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(ueCb->hdFddCb)),
185 sizeof(RgSchUeHdFddCb));
186 ueCb->hdFddEnbld = FALSE;
190 } /* rgSCHHdFddUeDel */
195 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
200 * Function: rgSCHCmnHdFddPtUlMrk
201 * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission
204 * @param[in] RgSchCellCb *cell
208 Void rgSCHCmnHdFddPtUlMrk(RgSchCellCb *cellCb)
210 uint16_t sfn; /* System Frame Number */
211 uint32_t pti; /* Index into Periodic table */
212 uint16_t sfi; /* Index into HDFDD state table */
221 CmLteTimingInfo timeInfo;
222 RgSchUePCqiCb *cqiCb = NULLP;
223 RgSchUePCqiCb *riCb = NULLP;
226 timeInfo = cellCb->crntTime;
228 /* Determine indexes */
229 pti = RG_SCH_HDFDD_GETPTI(timeInfo);
230 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_DELTA);
231 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_DELTA);
233 /* Get PT entries for */
234 cqiLst = &cellCb->pCqiSrsSrLst[pti].cqiLst;
235 srsLst = &cellCb->pCqiSrsSrLst[pti].srsLst;
236 srLst = &cellCb->pCqiSrsSrLst[pti].srLst;
237 riLst = &cellCb->pCqiSrsSrLst[pti].riLst;
239 /* Get first node in each list */
240 CM_LLIST_FIRST_NODE(cqiLst, cqiNode);
241 CM_LLIST_FIRST_NODE(srsLst, srsNode);
242 CM_LLIST_FIRST_NODE(riLst, riNode);
243 CM_LLIST_FIRST_NODE(srLst, srNode);
245 /* Mark corresponding the subframe as uplink control */
246 while ((NULLP != cqiNode ) &&
247 (NULLP != srsNode ) &&
248 (NULLP != srNode ) &&
251 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
252 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
253 RG_SCH_HDFDD_UL, sfn, sfi);
254 /* SRS Transmission instances */
255 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srsNode->node,
256 RG_SCH_HDFDD_UL, sfn, sfi);
257 /* SR Transmission instances */
258 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srNode->node,
259 RG_SCH_HDFDD_UL, sfn, sfi);
260 /* RI Transmission instances */
261 riCb = (RgSchUePCqiCb *)(riNode->node);
262 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
263 RG_SCH_HDFDD_UL, sfn, sfi);
265 /* Get next UeCb for all lists */
266 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
267 CM_LLIST_NEXT_NODE(srsLst, srsNode);
268 CM_LLIST_NEXT_NODE(srLst, srNode);
269 CM_LLIST_NEXT_NODE(riLst, riNode);
272 while ( NULLP != cqiNode)
274 /* CQI/PMI Transmission instances */
275 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
276 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
277 RG_SCH_HDFDD_UL, sfn, sfi);
278 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
280 while( NULLP != srsNode)
282 /* SRS Transmission instances */
283 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srsNode->node),
284 RG_SCH_HDFDD_UL, sfn, sfi);
285 CM_LLIST_NEXT_NODE(srsLst, srsNode);
287 while( NULLP != srNode)
289 /* SR Transmission instances */
290 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srNode->node),
291 RG_SCH_HDFDD_UL, sfn, sfi);
292 CM_LLIST_NEXT_NODE(srLst, srNode);
294 while( NULLP != riNode)
296 /* RI Transmission instances */
297 riCb = (RgSchUePCqiCb *)(riNode->node);
298 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
299 RG_SCH_HDFDD_UL, sfn, sfi);
300 CM_LLIST_NEXT_NODE(riLst, riNode);
304 } /* rgSCHCmnHdFddPtUlMrk */
305 #endif /* ifdef TFU_UPGRADE */
309 /* @brief Decides whether UE can be allowed for DL in given subframe
313 * Function : rgSCHCmnHdFddChkUlAllow
315 * Invoking Module Processing:
316 * - This shall be invoked by schedulars before allocating UL grants .
319 * - if Half Duplex is enabled
320 * - If ue->sf[reqsf].state is "DONWLINK"
321 * set alloweUlSch=FALSE
323 * set alloweUlSch=TRUE
324 * This function Marking for BCCH/PCCH occasions is also done
326 * @param[in] RgSchCellCb *cell
327 * @param[in] RgSchUeCb *ue
332 Void rgSCHCmnHdFddChkUlAllow(RgSchCellCb *cellCb,RgSchUeCb *ueCb,uint8_t *allow)
336 CmLteTimingInfo timeInfo;
337 RgSchDlSf *sf = NULLP; /* Dl subframe info */
340 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
344 timeInfo = cellCb->crntTime;
346 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
347 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
348 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset);
350 /* Set default value */
353 /* Validate condition 1 */
354 /* For (curretn time + DL_DELTA)th sf */
356 /* Also get subframe pointer to fetch Common Ch allocation */
357 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
360 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
362 /* Validate condition 2 */
363 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
365 /* Common channel scheduled */
366 /* Mark the BCCH/PCCH occasion */
367 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
368 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
371 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
372 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA ||
373 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLCNTRL))
375 /* Downlink scheduled */
377 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
382 /* Validate condition 3 */
383 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf
384 - i.e. next HARQ Feedback occasion */
385 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
386 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
387 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
388 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
390 /* No place for HARQ feedback */
392 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
397 /* Validate condition 4 */
398 /* For (curretn time + DL_DELTA - HRQ_DELTA)th sf
399 - i.e. previous HARQ Feedback occasion */
400 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
401 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
402 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
403 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
406 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
411 /* Validate condition 5 */
412 /* For (curretn time + DL_DELTA - 1)th sf -i.e. Guard time */
413 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
414 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
415 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
416 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA))
418 /* This subframe may be a switching gaurd time */
420 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
425 /* Adition guard time rule check: Above check is only for PDSCH, lets check
426 is there is any BCCH/PCCH data scheduled */
427 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo,
428 (ulOffset - RG_SCH_HDFDD_GRDTIM_DUR));
429 /* Also get subframe pointer to fetch Common Ch allocation */
430 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
431 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
433 /* Common channel scheduled */
434 /* Mark the BCCH/PCCH occasion */
435 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
437 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
443 /* All validation done. Safe to for UL */
446 } /* rgSCHCmnHdFddChkUlAllow */
449 /* @brief Decides whether UE can be allowed for UL in given subframe
453 * Function : rgSCHCmnHdFddChkDlAllow
455 * Invoking Module Processing:
456 * - This shall be invoked by schedulars before allocating for DL.
459 * Condition 1: subframe n + DL_DELTA should not be uplink
460 * Condition 2: subframe n+ DL_DELTA + 1 should meet guard time
461 * creation rule. For more
462 * information refer to section "2.25.7.1 Guard time
464 * Condition 3: subframe n + DL_DELTA + HRQ_DELTA should not be
465 * downlink so that downlink data (HARQ Feedback)
466 * can be received in next 4 subframe. {n + 7} Above
468 * be validated by taking SFN number into consideration.
469 * if all conditions are met then *allow is set to TRUE or lese to
471 * if hd-fdd is not anabled for this UE, then *allow is always TRUE.
474 * @param[in] RgSchCellCb *cellCb
475 * @param[in] RgSchUeCb *ueCb
476 * @param[in] CmLteTimingInfo *timeInfo
477 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
478 * Valdity of this pointer is not done in this function
481 Void rgSCHCmnHdFddChkDlAllow
485 Bool *allow /* Valdity of this pointer is not done in this function */
490 RgSchDlSf *sf = NULLP; /* Dl subframe info */
491 CmLteTimingInfo timeInfo;
492 CmLteTimingInfo tempTimeInfo;
496 timeInfo = cellCb->crntTime;
497 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
499 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
501 /* Also get subframe pointer to fetch Common Ch allocation */
502 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
504 /* Validate condition 1 */
505 /* For (curretn time + DL_DELTA)th sf */
507 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
509 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
510 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
512 /* Uplink scheduled */
513 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
518 /* It is not validation, but BCCH/PCCH marking is done here */
519 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
521 /* Common channel scheduled */
522 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
525 /* Validate condition 2 */
526 /* For (curretn time + DL_DELTA + 1)th sf -i.e. Guard time */
527 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
528 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
529 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
530 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
532 /* This subframe may be a switching guard time */
533 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: Guard time rule not met, ueId=%d ",
539 /* Validate condition 3 */
540 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
543 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
544 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
546 /* First check for any Common channel info is scheduled */
547 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL)
548 /* Also get subframe pointer to fetch Common Ch allocation */
549 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
550 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
552 /* Common channel scheduled */
553 /* Do the marking for this subframe */
554 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
555 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkDlAllow: Possible systemInfo, ueId=%d ",
559 /* Check for actual validation condition 3 */
560 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
561 ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
563 /* No place for HARQ feedback */
564 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
568 /* Mark this sf as DLCNTRL */
569 ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
574 /* If we are here then, subframe at HARQth location can be UL.
575 But check if Guard violation is done */
576 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
577 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
578 /* check for any Common channel info is scheduled */
579 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, (RG_SCH_CMN_HARQ_INTERVAL-1))
580 /* Also get subframe pointer to fetch Common Ch allocation */
581 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
582 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
584 /* Common channel scheduled */
585 /* Do the marking for this subframe */
586 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
587 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkDlAllow: (GT) Possible systemInfo, ueId=%d ",
591 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
592 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
594 /* No place for HARQ feedback */
595 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkDlAllow: (GT) No place for HARQ feedback,"
596 "ueId=%d ",ueCb->ueId);
601 /* First check for any Common channel info is scheduled */
604 /* All validation done. Safe to for DL */
606 } /* rgSCHCmnHdFddChkDlAllow */
610 /* @brief Decides whether NACK can be sent in a given subrame
614 * Function : rgSCHCmnHdFddChkNackAllow
616 * Invoking Module Processing:
617 * - This shall be invoked by schedulars.
619 * @param[in] RgSchUeCb *ue
625 Void rgSCHCmnHdFddChkNackAllow(RgSchCellCb *cellCb,RgSchUeCb *ueCb,CmLteTimingInfo timeInfo,Bool *sndNACK)
628 CmLteTimingInfo tempTimeInfo;
630 /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
634 /* Determine SFN and sf index for current subframe.
635 Note: Round function used as example */
636 tempTimeInfo = timeInfo;
637 RGSCH_INCR_SUB_FRAME(tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL);
639 /* Also get subframe pointer to fetch Common Ch allocation */
640 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
642 /* Check is this subframe has any Common Channel info scheduled */
643 if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
645 /* Yes, Cannot send NACK */
646 DU_LOG("\nERROR --> SCH : rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
652 /* safe, Send NACK */
653 DU_LOG("\nDEBUG --> SCH : rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
659 } /* rgSCHCmnHdFddChkNackAllow */
664 /* @brief makes final marking for HD-FDD UL allocations
668 * Function : rgSCHCmnHdFddUpdULMark
670 * Invoking Module Processing:
671 * - This shall be invoked by schedulars at the time of UL allocation
676 * @param[in] RgSchCellCb *cellCb
677 * @param[in] RgSchUeCb *ueCb
678 * @param[in] CmLteTimingInfo *timeInfo
679 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
680 * Valdity of this pointer is not done in this function.
684 Void rgSCHCmnHdFddUpdULMark(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
689 CmLteTimingInfo timeInfo;
692 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
693 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
694 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset)
697 /* Mark (n + UL_DELTA)th subframe as UL */
699 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
701 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
703 /* Mark (n + UL_DELTA + HARQ_DELTA)th subframe as DL */
704 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
705 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
706 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
708 /* Mark (n + UL_DELTA - HARQ_DELTA)th subframe as DL */
709 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
710 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
711 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_DLDATA)
713 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
716 /* Mark (n + UL_DELTA - 1)th subframe as DL_CNTRL */
717 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
718 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
719 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
721 /* Remove marking for older subframes */
723 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (S16)(ulOffset * -1));
724 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (ulOffset * -1));
725 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_NOSCHD, RG_SCH_HDFDD_INVSFN, sfi);
728 } /* rgSCHCmnHdFddUpdULMark */
733 /* @brief makes final marking for HD-FDD DL allocations
737 * Function : rgSCHCmnHdFddUpdDLMark
739 * Invoking Module Processing:
740 * - This shall be invoked by schedulars at the time of DL allocation
745 * @param[in] RgSchCellCb *cellCb
746 * @param[in] RgSchUeCb *ueCb
747 * @param[in] CmLteTimingInfo *timeInfo
748 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowed.
749 * Valdity of this pointer is not done in this function
754 Void rgSCHCmnHdFddUpdDLMark(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
759 CmLteTimingInfo timeInfo;
761 timeInfo = cellCb->crntTime;
762 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
764 /* Mark (n + DL_DELTA)th subframe as DL */
766 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
768 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
770 /* Mark (n + 1)th subframe as DL_CNTRL */
771 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
772 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
773 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
775 /* Mark (n + DL_DELTA + HARQ_DELTA )th subframe as UL */
776 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
777 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
778 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
780 /* Mark (n + DL_DELTA + HARQ_DELTA - 1)th subframe
781 as DL control for Guard period */
782 RG_SCH_HDFDD_GETSFN(sfn, timeInfo,
783 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
784 RG_SCH_HDFDD_GETSFI(sfi, timeInfo,
785 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
786 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
788 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
792 } /* rgSCHCmnHdFddUpdDLMark */
795 /* @brief determines effective SFN
799 * Function : rgSCHHdFddGetSfn
801 * Invoking Module Processing:
802 * Any HD-FDD module can invoke this function.
806 * @param[out] *sfn uint32_t
807 * @param[in] timeInfo timing information subframe of interest
808 * @param[in] offsest Offest with w.r.t which SFN has to be determined
813 Void rgSCHHdFddGetSfn(uint16_t *sfn,CmLteTimingInfo timeInfo,S16 offset)
818 if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
820 /* Increament to number of times of SFNs that can be possible
822 tempSfn = (timeInfo.sfn +
823 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
824 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
828 if(((S16)(timeInfo.subframe) + offset) < 0)
830 /* If negative, then definitely at least previous SFN */
831 tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
833 /* Now find how many more times we need to decreament */
834 tempSfCount = timeInfo.subframe + offset;
835 RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
839 /* No change in sfn */
840 tempSfn = timeInfo.sfn;
846 } /* End of rgSCHHdFddGetSfn */
852 #endif /* __cplusplus */
854 #endif /* LTEMAC_HDFDD */
859 /**********************************************************************
862 **********************************************************************/