Commit 673ef5fa authored by Xenofon Foukas's avatar Xenofon Foukas

Modified active harq reporting mechanism to support long schedule ahead of time values

parent d4fd0878
...@@ -81,6 +81,11 @@ enum openair_SYNCH_STATUS { ...@@ -81,6 +81,11 @@ enum openair_SYNCH_STATUS {
openair_SCHED_EXIT openair_SCHED_EXIT
}; };
enum openair_HARQ_TYPE {
openair_harq_DL = 0,
openair_harq_UL,
openair_harq_RA
};
#define DAQ_AGC_ON 1 #define DAQ_AGC_ON 1
#define DAQ_AGC_OFF 0 #define DAQ_AGC_OFF 0
......
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
/*! \file phy_procedures_lte_eNB.c /*! \file phy_procedures_lte_eNB.c
* \brief Implementation of eNB procedures from 36.213 LTE specifications * \brief Implementation of eNB procedures from 36.213 LTE specifications
* \author R. Knopp, F. Kaltenberger, N. Nikaein * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas
* \date 2011 * \date 2011
* \version 0.1 * \version 0.1
* \company Eurecom * \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk
* \note * \note
* \warning * \warning
*/ */
...@@ -141,26 +141,23 @@ uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_su ...@@ -141,26 +141,23 @@ uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_su
void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid) 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; if (harq_pid >=0 && harq_pid < 8) {
DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10; DLSCH_ptr->harq_pid_freelist[harq_pid] = 1;
} else {
LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
abort();
}
} }
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid) void remove_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__); if (harq_pid >=0 && harq_pid < 8) {
abort(); DLSCH_ptr->harq_pid_freelist[harq_pid] = 0;
} } else {
/* basic check, in case several threads deal with the free list at the same time
* in normal situations it should not happen, that's also why we don't use any
* locking mechanism to protect the free list
* to be refined in case things don't work properly
*/
if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__); LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
abort(); abort();
} }
DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
} }
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB) int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
...@@ -257,12 +254,17 @@ int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB) ...@@ -257,12 +254,17 @@ int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB)
return(-1); return(-1);
} }
int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag) int prev_frame = -1;
int prev_subframe = -1;
int prev_harq_pid = 0;
int prev_harq_round = 0;
int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t harq_flag)
{ {
LTE_eNB_DLSCH_t *DLSCH_ptr; LTE_eNB_DLSCH_t *DLSCH_ptr;
LTE_eNB_ULSCH_t *ULSCH_ptr; LTE_eNB_ULSCH_t *ULSCH_ptr;
uint8_t ulsch_subframe,ulsch_frame; uint8_t ulsch_subframe,ulsch_frame;
uint8_t i; uint8_t i, j;
int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]); int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7; int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
...@@ -272,39 +274,74 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16 ...@@ -272,39 +274,74 @@ int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16
return(-1); return(-1);
} }
if (ul_flag == 0) {// this is a DL request if ((harq_flag == openair_harq_DL) || (harq_flag == openair_harq_RA)) {// this is a DL request
DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0]; DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0];
if (harq_flag == openair_harq_RA) {
if (DLSCH_ptr->harq_processes[0] != NULL) {
*harq_pid = 0;
*round = DLSCH_ptr->harq_processes[0]->round;
return 0;
} else {
return -1;
}
}
if (prev_frame == frame && prev_subframe == subframe) {
*harq_pid = prev_harq_pid;
*round = prev_harq_round;
return (0);
}
// set to no available process first // set to no available process first
*harq_pid = -1; *harq_pid = -1;
for (i=0; i<DLSCH_ptr->Mdlharq; i++) { j = prev_harq_pid;
if (DLSCH_ptr->harq_processes[i]!=NULL) {
if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) { for (i = 0; i < 8; i++) {
sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe; j = (j + 1) % 8;
if (sf2<=sf1) if (DLSCH_ptr->harq_processes[j] != NULL) {
if (DLSCH_ptr->harq_processes[j]->status == ACTIVE) {
sf2 = (DLSCH_ptr->harq_processes[j]->frame*10) + DLSCH_ptr->harq_processes[j]->subframe;
if (sf2<=sf1) {
sfdiff = sf1-sf2; sfdiff = sf1-sf2;
else // this happens when wrapping around 1024 frame barrier } else { // this happens when wrapping around 1024 frame barrier
sfdiff = 10240 + sf1-sf2; sfdiff = 10240 + sf1-sf2;
LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff); }
LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[j]->round,sfdiff);
if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms) if (sfdiff > sfdiff_max) {
sfdiff_max = sfdiff; prev_harq_pid = j;
*harq_pid = i; prev_harq_round = DLSCH_ptr->harq_processes[j]->round;
*round = DLSCH_ptr->harq_processes[i]->round; prev_frame = frame;
prev_subframe = subframe;
*harq_pid = j;
*round = DLSCH_ptr->harq_processes[j]->round;
LOG_D(PHY,"process %d, %d is the allocated process\n", *harq_pid, *round);
return 0;
}
} else { // Send from the freelist
if (DLSCH_ptr->harq_pid_freelist[j] == 1) {
*harq_pid = j;
*round = 0;
prev_harq_pid = *harq_pid;
prev_harq_round = *round;
prev_frame = frame;
prev_subframe = subframe;
LOG_D(PHY,"process %d is first free process\n", *harq_pid);
return 0;
} }
} }
} else { // a process is not defined } else {
LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id); LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
return(-1); return(-1);
} }
} }
/* if no active harq pid, get the oldest in the freelist, if any */ if (*harq_pid == 255) {
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; *round = 0;
LOG_D(PHY,"process %d is first free process\n", *harq_pid); LOG_I(PHY, "TEST, no process found\n");
return -1;
} }
LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n", LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "PHY/extern.h" #include "PHY/extern.h"
#include "log.h" #include "log.h"
#include "SCHED/defs.h"
#include "RRC/LITE/extern.h" #include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "rrc_eNB_UE_context.h" #include "rrc_eNB_UE_context.h"
...@@ -671,7 +672,7 @@ int get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, const i ...@@ -671,7 +672,7 @@ int get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id, const i
uint16_t rnti = get_ue_crnti(mod_id,ue_id); uint16_t rnti = get_ue_crnti(mod_id,ue_id);
mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,0); mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&round,openair_harq_DL);
*id = harq_pid; *id = harq_pid;
if (round > 0) { if (round > 0) {
......
...@@ -661,7 +661,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un ...@@ -661,7 +661,7 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \n", LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \n",
module_idP,CC_id,frameP,subframeP); module_idP,CC_id,frameP,subframeP);
// Get candidate harq_pid from PHY // Get candidate harq_pid from PHY
mac_xface->get_ue_active_harq_pid(module_idP,CC_id,RA_template->rnti,frameP,subframeP,&harq_pid,&round,0); mac_xface->get_ue_active_harq_pid(module_idP,CC_id,RA_template->rnti,frameP,subframeP,&harq_pid,&round,openair_harq_RA);
if (round>0) { if (round>0) {
//RA_template->wait_ack_Msg4++; //RA_template->wait_ack_Msg4++;
......
...@@ -753,7 +753,7 @@ void schedule_ulsch_rnti(module_id_t module_idP, ...@@ -753,7 +753,7 @@ void schedule_ulsch_rnti(module_id_t module_idP,
DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu; DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_template = &UE_list->UE_template[CC_id][UE_id];
if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) { if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL) == -1 ) {
LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n", LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
module_idP,frameP,subframeP, UE_id, CC_id, rnti); module_idP,frameP,subframeP, UE_id, CC_id, rnti);
// NN --> RK: Don't schedule UE if we cannot get harq pid // NN --> RK: Don't schedule UE if we cannot get harq pid
......
...@@ -760,7 +760,7 @@ void dlsch_scheduler_pre_processor_reset (int module_idP, ...@@ -760,7 +760,7 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
frameP,subframeP, frameP,subframeP,
&ue_sched_ctl->harq_pid[CC_id], &ue_sched_ctl->harq_pid[CC_id],
&ue_sched_ctl->round[CC_id], &ue_sched_ctl->round[CC_id],
0); openair_harq_DL);
if (ue_sched_ctl->ta_timer == 0) { if (ue_sched_ctl->ta_timer == 0) {
// WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...
...@@ -1020,7 +1020,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP, ...@@ -1020,7 +1020,7 @@ void ulsch_scheduler_pre_processor(module_id_t module_idP,
// This is the actual CC_id in the list // This is the actual CC_id in the list
CC_id = UE_list->ordered_ULCCids[n][UE_id]; CC_id = UE_list->ordered_ULCCids[n][UE_id];
mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1); mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL);
if(round>0) { if(round>0) {
nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; nb_allocated_rbs[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment