diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index a77501e14c78357872f489c2f5b3c33e7a958c68..49d83aadef1c6a8c13b2eac3e2c44b7c656dfdd0 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1102,8 +1102,12 @@ int generate_eNB_dlsch_params_from_dci(int frame, dlsch[0]->harq_ids[subframe] = harq_pid; - if (dlsch0_harq->round == 0) + if (dlsch0_harq->round == 0) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch[0], harq_pid); dlsch0_harq->status = ACTIVE; + } break; @@ -1237,6 +1241,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (dlsch0_harq->round == 0) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch[0], harq_pid); dlsch0_harq->status = ACTIVE; // printf("Setting DLSCH process %d to ACTIVE\n",harq_pid); // MCS and TBS don't change across HARQ rounds @@ -1605,10 +1612,16 @@ int generate_eNB_dlsch_params_from_dci(int frame, // reset HARQ process if this is the first transmission if (dlsch0_harq->round == 0) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch0, harq_pid); dlsch0_harq->status = ACTIVE; } if (dlsch1_harq->round == 0) { + /* necessary test? */ + if (dlsch1_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch1, harq_pid); dlsch1_harq->status = ACTIVE; } @@ -1986,10 +1999,16 @@ int generate_eNB_dlsch_params_from_dci(int frame, // reset HARQ process if this is the first transmission if ((dlsch0->active==1) && (dlsch0_harq->round == 0)) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch0, harq_pid); dlsch0_harq->status = ACTIVE; } if ((dlsch1->active==1) && (dlsch1_harq->round == 0)) { + /* necessary test? */ + if (dlsch1_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch1, harq_pid); dlsch1_harq->status = ACTIVE; } @@ -2131,16 +2150,23 @@ int generate_eNB_dlsch_params_from_dci(int frame, // check if either TB is disabled (see 36-213 V8.6 p. 26) - if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) + if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { + LOG_W(PHY, "what to do with respect to get_harq_pid_from_freelist?\n"); dlsch0_harq->status = DISABLED; + } - if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) + if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { + LOG_W(PHY, "what to do with respect to get_harq_pid_from_freelist?\n"); dlsch1_harq->status = DISABLED; + } dlsch0_harq->Nl = 1; if (dlsch0_harq->round == 0) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch0, harq_pid); dlsch0_harq->status = ACTIVE; // printf("Setting DLSCH process %d to ACTIVE\n",harq_pid); } @@ -2305,11 +2331,17 @@ int generate_eNB_dlsch_params_from_dci(int frame, if ((dlsch0_harq->round == 0) && (dlsch0->active == 1) ) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch0, harq_pid); dlsch0_harq->status = ACTIVE; dlsch0_harq->mcs = mcs1; } if ((dlsch1_harq->round == 0) && (dlsch1->active == 1) ) { + /* necessary test? */ + if (dlsch1_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch1, harq_pid); dlsch1_harq->status = ACTIVE; dlsch1_harq->mcs = mcs2; } @@ -2473,6 +2505,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, if (dlsch0_harq->round == 0) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch0, harq_pid); dlsch0_harq->status = ACTIVE; // printf("Setting DLSCH process %d to ACTIVE\n",harq_pid); } @@ -2602,6 +2637,9 @@ int generate_eNB_dlsch_params_from_dci(int frame, // dlsch0_harq->Ndi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi; if (dlsch0_harq->round == 0) { + /* necessary test? */ + if (dlsch0_harq->status == SCH_IDLE) + get_harq_pid_from_freelist(dlsch0, harq_pid); dlsch0_harq->status = ACTIVE; // printf("Setting DLSCH process %d to ACTIVE\n",harq_pid); } diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h index a21693fea0e9865aa11ec495cecaf3a001006fd4..55b9c4fe4453772d8177e36f92718b55e545834a 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs.h +++ b/openair1/PHY/LTE_TRANSPORT/defs.h @@ -258,6 +258,13 @@ typedef struct { uint8_t error_threshold; /// Pointers to 8 HARQ processes for the DLSCH LTE_DL_eNB_HARQ_t *harq_processes[8]; + /// circular list of free harq PIDs (the oldest come first) + /// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE) + int harq_pid_freelist[10]; + /// the head position of the free list (if list is free then head=tail) + int head_freelist; + /// the tail position of the free list + int tail_freelist; /// Number of soft channel bits uint32_t G; /// Codebook index for this dlsch (0,1,2,3) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 83066480b49e966bc485fb9e38323171c504bbc0..f051dc3ecfe9869bf993c4dfe06ea61e0edf793c 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -152,6 +152,9 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne for (i=0; i<10; i++) dlsch->harq_ids[i] = Mdlharq; + dlsch->head_freelist = 0; + dlsch->tail_freelist = 0; + for (i=0; i<Mdlharq; i++) { dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t)); LOG_T(PHY, "Required mem size %d (bw scaling %d), dlsch->harq_processes[%d] %p\n", @@ -192,6 +195,8 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,unsigne msg("Can't get harq_p %d\n",i); exit_flag=3; } + + put_harq_pid_in_freelist(dlsch, i); } if (exit_flag==0) { diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h index bebe476dcd2fd3ab194549d5cfdb39fd2dfb2ecd..34c814a3c8b5bcbeb5e53f71abc0af4e749dab69 100644 --- a/openair1/SCHED/defs.h +++ b/openair1/SCHED/defs.h @@ -401,6 +401,8 @@ uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1); int get_nCCE_offset(unsigned char L, int nCCE, int common_dci, unsigned short rnti, unsigned char subframe); +void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid); +void get_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid); int8_t find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 28d50ec1ad99e0b66ab79e7dc2dfd4127d08a86d..4d5971c07429a4ac1d52011585be7b581f1a8f6b 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -136,6 +136,21 @@ uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_su return(0); } +void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid) +{ + DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->tail_freelist] = harq_pid; + DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10; +} + +void get_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid) +{ + if (DLSCH_ptr->head_freelist == DLSCH_ptr->tail_freelist) { + LOG_E(PHY, "%s:%d: you cannot read this!\n", __FILE__, __LINE__); + abort(); + } + DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10; +} + int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB) { uint8_t i; @@ -178,6 +193,7 @@ int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB) int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction_flag) { uint8_t i; + int j; for (i=0; i<NUMBER_OF_UE_MAX; i++) { if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) { @@ -196,6 +212,13 @@ int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction //phy_vars_eNB->eNB_UE_stats[i].crnti = 0; memset(&phy_vars_eNB->eNB_UE_stats[i],0,sizeof(LTE_eNB_UE_stats)); // mac_exit_wrapper("Removing UE"); + + /* clear the harq pid freelist */ + phy_vars_eNB->dlsch_eNB[i][0]->head_freelist = 0; + phy_vars_eNB->dlsch_eNB[i][0]->tail_freelist = 0; + for (j = 0; j < 8; j++) + put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], j); + return(i); } } @@ -248,18 +271,7 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16 for (i=0; i<DLSCH_ptr->Mdlharq; i++) { if (DLSCH_ptr->harq_processes[i]!=NULL) { - if (DLSCH_ptr->harq_processes[i]->status != ACTIVE) { - // store first inactive process - if (hp2sf[i] == subframe && first_proc_found == 0) { - first_proc_found = 1; - *harq_pid = i; - *round = 0; - LOG_D(PHY,"process %d is first free process\n",i); - } - else { - LOG_D(PHY,"process %d is free\n",i); - } - } else { + if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) { sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe; if (sf2<=sf1) sfdiff = sf1-sf2; @@ -279,6 +291,14 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16 return(-1); } } + + /* if no active harq pid, get the oldest in the freelist, if any */ + if (*harq_pid == 255 && DLSCH_ptr->head_freelist != DLSCH_ptr->tail_freelist) { + *harq_pid = DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]; + *round = 0; + LOG_D(PHY,"process %d is first free process\n", *harq_pid); + } + LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n", frame,subframe,*harq_pid); } else { // This is a UL request @@ -297,7 +317,6 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16 return(0); } - int CCE_table[800]; void init_nCCE_table(void) @@ -2869,6 +2888,7 @@ void process_HARQ_feedback(uint8_t UE_id, dlsch_harq_proc->round = 0; ue_stats->dlsch_l2_errors[dl_harq_pid[m]]++; dlsch_harq_proc->status = SCH_IDLE; + put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]); dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq; } } else { @@ -2881,6 +2901,7 @@ void process_HARQ_feedback(uint8_t UE_id, // Received ACK so set round to 0 and set dlsch_harq_pid IDLE dlsch_harq_proc->round = 0; dlsch_harq_proc->status = SCH_IDLE; + put_harq_pid_in_freelist(dlsch, dl_harq_pid[m]); dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq; ue_stats->total_TBS = ue_stats->total_TBS + @@ -3950,6 +3971,9 @@ void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_ phy_vars_eNB->eNB_UE_stats[i].sr_received++; if (phy_vars_eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 + /* is this test necessary? */ + if (phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status != SCH_IDLE) + put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], 0); phy_vars_eNB->first_sr[i] = 0; phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->round=0; phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status=SCH_IDLE;