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
95 S16 rgSCHHdFddUeCfg(RgSchCellCb *cellCb,RgSchUeCb *ueCb,Bool hdFddEnbl)
99 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
100 "rgSCHHdFddUeCfg(): UeId =%d hdFddEnbl=%d",
101 ueCb->ueId, hdFddEnbl);
102 if(ueCb->hdFddEnbld == TRUE)
104 if (hdFddEnbl == FALSE)
106 /* Do not allow switch from HD-FDD to FD-FDD configuration */
107 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
108 "rgSCHHdFddUeCfg(): HD-FDD to FD-FDD Configuration is not allowed"
109 "CRNTI:%d",ueCb->ueId);
113 /* If already enabled then it can be second reconfiguration */
114 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
115 "rgSCHHdFddUeCfg(): HD-FDD already enabled for this UE"
116 "CRNTI:%d",ueCb->ueId);
122 /* Check is SPS enabled for this UE */
123 if(hdFddEnbl == TRUE &&
124 (ueCb->ul.ulSpsCfg.isUlSpsEnabled == TRUE ||
125 ueCb->dl.dlSpsCfg.isDlSpsEnabled == TRUE))
127 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
128 "rgSCHHdFddUeCfg(): Could'nt do HDFDD cfg, SPS already configured"
129 "CRNTI:%d",ueCb->ueId);
134 ueCb->hdFddEnbld = hdFddEnbl;
135 if( hdFddEnbl == TRUE)
137 rgSCHUtlAllocSBuf(cellCb->instIdx,(Data **) &ueCb->hdFddCb,
138 sizeof(RgSchUeHdFddCb));
139 if (ueCb->hdFddCb != NULLP)
141 for (sfi = 0; sfi < RG_SCH_HDFDD_NUMSFINFO; sfi++)
143 ueCb->hdFddCb->subfrm[sfi].subFrmDir = RG_SCH_HDFDD_NOSCHD;
144 ueCb->hdFddCb->subfrm[sfi].sfn = RG_SCH_HDFDD_INVSFN;
146 /* Add this UE to list maintained in CellCb */
147 /* cmLListAdd2Tail(&cellCb->hdFddLst,&ueCb->hdFddCb->hdFddLstEnt); */
151 RLOG_ARG1(L_ERROR,DBG_CELLID,cellCb->cellId,
152 "rgSCHHdFddUeCfg(): Could not allocate memory for hd-fdd ueCb"
153 "CRNTI:%d",ueCb->ueId);
161 /* @brief Frees Half Duplex related data structures
165 * Function : rgSCHHdFddUeDel
167 * Invoking Module Processing:
168 * - This shall be invoked by SCH_GOM at Ue deletion.
171 * - if Half Duplex is enabled
172 * - if (ueCb->hdFddCb != NULL)
173 * - Remove ue from cellCb->hdUeLstCp;
178 * @param[in] RgSchCellCb *cell
179 * @param[in] RgSchUeCb *ue
185 S16 rgSCHHdFddUeDel(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
188 RLOG_ARG2(L_DEBUG,DBG_CELLID,cellCb->cellId,
189 " rgSCHHdFddUeDel(): UeId =%d hdFdd=%x",
190 ueCb->ueId, ueCb->hdFddEnbld);
195 /* ccpu00117052 - MOD - Passing double pointer
196 for proper NULLP assignment*/
197 rgSCHUtlFreeSBuf(cellCb->instIdx, (Data **)(&(ueCb->hdFddCb)),
198 sizeof(RgSchUeHdFddCb));
199 ueCb->hdFddEnbld = FALSE;
203 } /* rgSCHHdFddUeDel */
208 /* @brief Mark the subframes as uplink for HD FDD if CQI/RI or SRS or RI is
213 * Function: rgSCHCmnHdFddPtUlMrk
214 * Purpose: Updation of Periodic CQI/PMI, SRS and SR tranmission
217 * @param[in] RgSchCellCb *cell
221 Void rgSCHCmnHdFddPtUlMrk(RgSchCellCb *cellCb)
223 uint16_t sfn; /* System Frame Number */
224 uint32_t pti; /* Index into Periodic table */
225 uint16_t sfi; /* Index into HDFDD state table */
234 CmLteTimingInfo timeInfo;
235 RgSchUePCqiCb *cqiCb = NULLP;
236 RgSchUePCqiCb *riCb = NULLP;
239 timeInfo = cellCb->crntTime;
241 /* Determine indexes */
242 pti = RG_SCH_HDFDD_GETPTI(timeInfo);
243 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_DELTA);
244 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_DELTA);
246 /* Get PT entries for */
247 cqiLst = &cellCb->pCqiSrsSrLst[pti].cqiLst;
248 srsLst = &cellCb->pCqiSrsSrLst[pti].srsLst;
249 srLst = &cellCb->pCqiSrsSrLst[pti].srLst;
250 riLst = &cellCb->pCqiSrsSrLst[pti].riLst;
252 /* Get first node in each list */
253 CM_LLIST_FIRST_NODE(cqiLst, cqiNode);
254 CM_LLIST_FIRST_NODE(srsLst, srsNode);
255 CM_LLIST_FIRST_NODE(riLst, riNode);
256 CM_LLIST_FIRST_NODE(srLst, srNode);
258 /* Mark corresponding the subframe as uplink control */
259 while ((NULLP != cqiNode ) &&
260 (NULLP != srsNode ) &&
261 (NULLP != srNode ) &&
264 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
265 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
266 RG_SCH_HDFDD_UL, sfn, sfi);
267 /* SRS Transmission instances */
268 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srsNode->node,
269 RG_SCH_HDFDD_UL, sfn, sfi);
270 /* SR Transmission instances */
271 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)srNode->node,
272 RG_SCH_HDFDD_UL, sfn, sfi);
273 /* RI Transmission instances */
274 riCb = (RgSchUePCqiCb *)(riNode->node);
275 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
276 RG_SCH_HDFDD_UL, sfn, sfi);
278 /* Get next UeCb for all lists */
279 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
280 CM_LLIST_NEXT_NODE(srsLst, srsNode);
281 CM_LLIST_NEXT_NODE(srLst, srNode);
282 CM_LLIST_NEXT_NODE(riLst, riNode);
285 while ( NULLP != cqiNode)
287 /* CQI/PMI Transmission instances */
288 cqiCb = (RgSchUePCqiCb *)(cqiNode->node);
289 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)(cqiCb->servCellInfo->ue),
290 RG_SCH_HDFDD_UL, sfn, sfi);
291 CM_LLIST_NEXT_NODE(cqiLst, cqiNode);
293 while( NULLP != srsNode)
295 /* SRS Transmission instances */
296 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srsNode->node),
297 RG_SCH_HDFDD_UL, sfn, sfi);
298 CM_LLIST_NEXT_NODE(srsLst, srsNode);
300 while( NULLP != srNode)
302 /* SR Transmission instances */
303 RG_SCH_HDFDD_VLDTANDMARK(((RgSchUeCb*)srNode->node),
304 RG_SCH_HDFDD_UL, sfn, sfi);
305 CM_LLIST_NEXT_NODE(srLst, srNode);
307 while( NULLP != riNode)
309 /* RI Transmission instances */
310 riCb = (RgSchUePCqiCb *)(riNode->node);
311 RG_SCH_HDFDD_VLDTANDMARK((RgSchUeCb*)riCb->servCellInfo->ue,
312 RG_SCH_HDFDD_UL, sfn, sfi);
313 CM_LLIST_NEXT_NODE(riLst, riNode);
317 } /* rgSCHCmnHdFddPtUlMrk */
318 #endif /* ifdef TFU_UPGRADE */
322 /* @brief Decides whether UE can be allowed for DL in given subframe
326 * Function : rgSCHCmnHdFddChkUlAllow
328 * Invoking Module Processing:
329 * - This shall be invoked by schedulars before allocating UL grants .
332 * - if Half Duplex is enabled
333 * - If ue->sf[reqsf].state is "DONWLINK"
334 * set alloweUlSch=FALSE
336 * set alloweUlSch=TRUE
337 * This function Marking for BCCH/PCCH occasions is also done
339 * @param[in] RgSchCellCb *cell
340 * @param[in] RgSchUeCb *ue
345 Void rgSCHCmnHdFddChkUlAllow(RgSchCellCb *cellCb,RgSchUeCb *ueCb,uint8_t *allow)
349 CmLteTimingInfo timeInfo;
350 RgSchDlSf *sf = NULLP; /* Dl subframe info */
353 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
354 " rgSCHCmnHdFddChkUlAllow: ueId=%d ", ueCb->ueId);
358 timeInfo = cellCb->crntTime;
360 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
361 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
362 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset);
364 /* Set default value */
367 /* Validate condition 1 */
368 /* For (curretn time + DL_DELTA)th sf */
370 /* Also get subframe pointer to fetch Common Ch allocation */
371 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
374 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
376 /* Validate condition 2 */
377 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
379 /* Common channel scheduled */
380 /* Mark the BCCH/PCCH occasion */
381 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
382 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
383 "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
386 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
387 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA ||
388 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLCNTRL))
390 /* Downlink scheduled */
392 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
393 "rgSCHCmnHdFddChkUlAllow: Already marked for DL, ueId = %d ",
398 /* Validate condition 3 */
399 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf
400 - i.e. next HARQ Feedback occasion */
401 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
402 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
403 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
404 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
406 /* No place for HARQ feedback */
408 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
409 "rgSCHCmnHdFddChkUlAllow: No Place for HARQ, ueId = %d ",
414 /* Validate condition 4 */
415 /* For (curretn time + DL_DELTA - HRQ_DELTA)th sf
416 - i.e. previous HARQ Feedback occasion */
417 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
418 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_CMN_HARQ_INTERVAL));
419 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
420 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL)
423 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
424 " rgSCHCmnHdFddChkUlAllow: No Place for UL grant, ueId = %d ",
429 /* Validate condition 5 */
430 /* For (curretn time + DL_DELTA - 1)th sf -i.e. Guard time */
431 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
432 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (-RG_SCH_HDFDD_GRDTIM_DUR));
433 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
434 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA))
436 /* This subframe may be a switching gaurd time */
438 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
439 " rgSCHCmnHdFddChkUlAllow: No Place for Guard time, ueId = %d ",
444 /* Adition guard time rule check: Above check is only for PDSCH, lets check
445 is there is any BCCH/PCCH data scheduled */
446 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo,
447 (ulOffset - RG_SCH_HDFDD_GRDTIM_DUR));
448 /* Also get subframe pointer to fetch Common Ch allocation */
449 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
450 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
452 /* Common channel scheduled */
453 /* Mark the BCCH/PCCH occasion */
454 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, timeInfo.sfn, sfi);
456 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
457 "rgSCHCmnHdFddChkUlAllow: Already marked for Cmn DL, ueId = %d ",
463 /* All validation done. Safe to for UL */
466 } /* rgSCHCmnHdFddChkUlAllow */
469 /* @brief Decides whether UE can be allowed for UL in given subframe
473 * Function : rgSCHCmnHdFddChkDlAllow
475 * Invoking Module Processing:
476 * - This shall be invoked by schedulars before allocating for DL.
479 * Condition 1: subframe n + DL_DELTA should not be uplink
480 * Condition 2: subframe n+ DL_DELTA + 1 should meet guard time
481 * creation rule. For more
482 * information refer to section "2.25.7.1 Guard time
484 * Condition 3: subframe n + DL_DELTA + HRQ_DELTA should not be
485 * downlink so that downlink data (HARQ Feedback)
486 * can be received in next 4 subframe. {n + 7} Above
488 * be validated by taking SFN number into consideration.
489 * if all conditions are met then *allow is set to TRUE or lese to
491 * if hd-fdd is not anabled for this UE, then *allow is always TRUE.
494 * @param[in] RgSchCellCb *cellCb
495 * @param[in] RgSchUeCb *ueCb
496 * @param[in] CmLteTimingInfo *timeInfo
497 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
498 * Valdity of this pointer is not done in this function
501 Void rgSCHCmnHdFddChkDlAllow
505 Bool *allow /* Valdity of this pointer is not done in this function */
510 RgSchDlSf *sf = NULLP; /* Dl subframe info */
511 CmLteTimingInfo timeInfo;
512 CmLteTimingInfo tempTimeInfo;
516 timeInfo = cellCb->crntTime;
517 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
519 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
520 "rgSCHCmnHdFddDlSchAll (): ueId=%d ", ueCb->ueId);
522 /* Also get subframe pointer to fetch Common Ch allocation */
523 sf = rgSCHUtlSubFrmGet(cellCb, timeInfo);
525 /* Validate condition 1 */
526 /* For (curretn time + DL_DELTA)th sf */
528 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
530 if ((ueCb->hdFddCb->subfrm[sfi].sfn == sfn) &&
531 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
533 /* Uplink scheduled */
534 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
535 "rgSCHCmnHdFddChkDlAllow: sf is UL, ueId=%d ", ueCb->ueId);
540 /* It is not validation, but BCCH/PCCH marking is done here */
541 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
543 /* Common channel scheduled */
544 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi); /* NOT_HIT */
547 /* Validate condition 2 */
548 /* For (curretn time + DL_DELTA + 1)th sf -i.e. Guard time */
549 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
550 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
551 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
552 (ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_UL))
554 /* This subframe may be a switching guard time */
555 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
556 " rgSCHCmnHdFddChkDlAllow: Guard time rule not met, ueId=%d ",
562 /* Validate condition 3 */
563 /* For (curretn time + DL_DELTA + HRQ_DELTA)th sf - i.e. next HARQ
566 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
567 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
569 /* First check for any Common channel info is scheduled */
570 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL)
571 /* Also get subframe pointer to fetch Common Ch allocation */
572 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
573 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
575 /* Common channel scheduled */
576 /* Do the marking for this subframe */
577 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
578 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
579 "rgSCHCmnHdFddChkDlAllow: Possible systemInfo, ueId=%d ",
583 /* Check for actual validation condition 3 */
584 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
585 ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
587 /* No place for HARQ feedback */
588 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
589 "rgSCHCmnHdFddChkDlAllow: No place for HARQ feedback, ueId=%d ",
593 /* Mark this sf as DLCNTRL */
594 ueCb->hdFddCb->subfrm[sfi].subFrmDir =RG_SCH_HDFDD_DLCNTRL;
599 /* If we are here then, subframe at HARQth location can be UL.
600 But check if Guard violation is done */
601 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
602 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL-1);
603 /* check for any Common channel info is scheduled */
604 RG_SCH_ADD_TO_CRNT_TIME(timeInfo, tempTimeInfo, (RG_SCH_CMN_HARQ_INTERVAL-1))
605 /* Also get subframe pointer to fetch Common Ch allocation */
606 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
607 if (RG_SCH_HDFDD_ISCMN_SCHED(sf))
609 /* Common channel scheduled */
610 /* Do the marking for this subframe */
611 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, tempTimeInfo.sfn, sfi);
612 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
613 "rgSCHCmnHdFddChkDlAllow: (GT) Possible systemInfo, ueId=%d ",
617 if (ueCb->hdFddCb->subfrm[sfi].sfn == sfn &&
618 ueCb->hdFddCb->subfrm[sfi].subFrmDir == RG_SCH_HDFDD_DLDATA)
620 /* No place for HARQ feedback */
621 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
622 "rgSCHCmnHdFddChkDlAllow: (GT) No place for HARQ feedback,"
623 "ueId=%d ",ueCb->ueId);
628 /* First check for any Common channel info is scheduled */
631 /* All validation done. Safe to for DL */
633 } /* rgSCHCmnHdFddChkDlAllow */
637 /* @brief Decides whether NACK can be sent in a given subrame
641 * Function : rgSCHCmnHdFddChkNackAllow
643 * Invoking Module Processing:
644 * - This shall be invoked by schedulars.
646 * @param[in] RgSchUeCb *ue
652 Void rgSCHCmnHdFddChkNackAllow(RgSchCellCb *cellCb,RgSchUeCb *ueCb,CmLteTimingInfo timeInfo,Bool *sndNACK)
655 CmLteTimingInfo tempTimeInfo;
657 /* Information in timeInfo contains (n+DL_DELTA) th subframe info*/
661 /* Determine SFN and sf index for current subframe.
662 Note: Round function used as example */
663 tempTimeInfo = timeInfo;
664 RGSCH_INCR_SUB_FRAME(tempTimeInfo, RG_SCH_CMN_HARQ_INTERVAL);
666 /* Also get subframe pointer to fetch Common Ch allocation */
667 sf = rgSCHUtlSubFrmGet(cellCb, tempTimeInfo);
669 /* Check is this subframe has any Common Channel info scheduled */
670 if(RG_SCH_HDFDD_ISCMN_SCHED(sf))
672 /* Yes, Cannot send NACK */
673 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
674 "rgSCHCmnHdFddChkNackAllow: Cannot send NACK, ueId = %d ",
680 /* safe, Send NACK */
681 RLOG_ARG1(L_DEBUG,DBG_CELLID,cellCb->cellId,
682 "rgSCHCmnHdFddChkNackAllow: NACk can be sent, ueId = %d ",
688 } /* rgSCHCmnHdFddChkNackAllow */
693 /* @brief makes final marking for HD-FDD UL allocations
697 * Function : rgSCHCmnHdFddUpdULMark
699 * Invoking Module Processing:
700 * - This shall be invoked by schedulars at the time of UL allocation
705 * @param[in] RgSchCellCb *cellCb
706 * @param[in] RgSchUeCb *ueCb
707 * @param[in] CmLteTimingInfo *timeInfo
708 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowedi.
709 * Valdity of this pointer is not done in this function.
713 Void rgSCHCmnHdFddUpdULMark(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
718 CmLteTimingInfo timeInfo;
721 ulOffset = RGSCH_PDCCH_PUSCH_DELTA -
722 TFU_CRCIND_ULDELTA + RGSCH_PDCCH_PUSCH_DELTA;
723 RG_SCH_ADD_TO_CRNT_TIME(cellCb->crntTime, timeInfo, ulOffset)
726 /* Mark (n + UL_DELTA)th subframe as UL */
728 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
730 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
732 /* Mark (n + UL_DELTA + HARQ_DELTA)th subframe as DL */
733 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
734 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
735 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
737 /* Mark (n + UL_DELTA - HARQ_DELTA)th subframe as DL */
738 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
739 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (0-RG_SCH_CMN_HARQ_INTERVAL));
740 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_DLDATA)
742 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
745 /* Mark (n + UL_DELTA - 1)th subframe as DL_CNTRL */
746 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
747 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, -RG_SCH_HDFDD_GRDTIM_DUR);
748 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
750 /* Remove marking for older subframes */
752 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, (S16)(ulOffset * -1));
753 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, (ulOffset * -1));
754 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_NOSCHD, RG_SCH_HDFDD_INVSFN, sfi);
757 } /* rgSCHCmnHdFddUpdULMark */
762 /* @brief makes final marking for HD-FDD DL allocations
766 * Function : rgSCHCmnHdFddUpdDLMark
768 * Invoking Module Processing:
769 * - This shall be invoked by schedulars at the time of DL allocation
774 * @param[in] RgSchCellCb *cellCb
775 * @param[in] RgSchUeCb *ueCb
776 * @param[in] CmLteTimingInfo *timeInfo
777 * @param[out] uint8_t *allow -- TRUE is allowed or FALSE if no allowed.
778 * Valdity of this pointer is not done in this function
783 Void rgSCHCmnHdFddUpdDLMark(RgSchCellCb *cellCb,RgSchUeCb *ueCb)
788 CmLteTimingInfo timeInfo;
790 timeInfo = cellCb->crntTime;
791 RGSCH_INCR_SUB_FRAME(timeInfo, RG_SCH_CMN_DL_DELTA);
793 /* Mark (n + DL_DELTA)th subframe as DL */
795 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, 0);
797 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLDATA, sfn, sfi);
799 /* Mark (n + 1)th subframe as DL_CNTRL */
800 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
801 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_HDFDD_GRDTIM_DUR);
802 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
804 /* Mark (n + DL_DELTA + HARQ_DELTA )th subframe as UL */
805 RG_SCH_HDFDD_GETSFN(sfn, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
806 RG_SCH_HDFDD_GETSFI(sfi, timeInfo, RG_SCH_CMN_HARQ_INTERVAL);
807 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_UL, sfn, sfi);
809 /* Mark (n + DL_DELTA + HARQ_DELTA - 1)th subframe
810 as DL control for Guard period */
811 RG_SCH_HDFDD_GETSFN(sfn, timeInfo,
812 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
813 RG_SCH_HDFDD_GETSFI(sfi, timeInfo,
814 (RG_SCH_CMN_HARQ_INTERVAL - RG_SCH_HDFDD_GRDTIM_DUR));
815 if (ueCb->hdFddCb->subfrm[sfi].subFrmDir != RG_SCH_HDFDD_UL)
817 RG_SCH_HDFDD_MARKSTATE(ueCb, RG_SCH_HDFDD_DLCNTRL, sfn, sfi);
821 } /* rgSCHCmnHdFddUpdDLMark */
824 /* @brief determines effective SFN
828 * Function : rgSCHHdFddGetSfn
830 * Invoking Module Processing:
831 * Any HD-FDD module can invoke this function.
835 * @param[out] *sfn uint32_t
836 * @param[in] timeInfo timing information subframe of interest
837 * @param[in] offsest Offest with w.r.t which SFN has to be determined
842 Void rgSCHHdFddGetSfn(uint16_t *sfn,CmLteTimingInfo timeInfo,S16 offset)
847 if(((S16)(timeInfo.subframe) + offset) >= RGSCH_NUM_SUB_FRAMES)
849 /* Increament to number of times of SFNs that can be possible
851 tempSfn = (timeInfo.sfn +
852 ((timeInfo.subframe + offset) / RGSCH_NUM_SUB_FRAMES))
853 & (RGSCH_MAX_SFN -1); /* Mod with MAX SFN supported */
857 if(((S16)(timeInfo.subframe) + offset) < 0)
859 /* If negative, then definitely at least previous SFN */
860 tempSfn = (timeInfo.sfn - 1) & (RGSCH_MAX_SFN -1);
862 /* Now find how many more times we need to decreament */
863 tempSfCount = timeInfo.subframe + offset;
864 RG_SCH_HDFDD_ROLLSFN(tempSfCount, tempSfn);
868 /* No change in sfn */
869 tempSfn = timeInfo.sfn;
875 } /* End of rgSCHHdFddGetSfn */
881 #endif /* __cplusplus */
883 #endif /* LTEMAC_HDFDD */
888 /**********************************************************************
891 **********************************************************************/