Modified active harq reporting mechanism to support long schedule ahead of time values
This commit is contained in:
@@ -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 @@
|
|||||||
|
|
||||||
/*! \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
|
|||||||
|
|
||||||
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)
|
|||||||
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
|
|||||||
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) {
|
|
||||||
sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
|
|
||||||
if (sf2<=sf1)
|
|
||||||
sfdiff = sf1-sf2;
|
|
||||||
else // this happens when wrapping around 1024 frame barrier
|
|
||||||
sfdiff = 10240 + sf1-sf2;
|
|
||||||
LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff);
|
|
||||||
|
|
||||||
if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms)
|
for (i = 0; i < 8; i++) {
|
||||||
sfdiff_max = sfdiff;
|
j = (j + 1) % 8;
|
||||||
*harq_pid = i;
|
if (DLSCH_ptr->harq_processes[j] != NULL) {
|
||||||
*round = DLSCH_ptr->harq_processes[i]->round;
|
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;
|
||||||
|
} else { // this happens when wrapping around 1024 frame barrier
|
||||||
|
sfdiff = 10240 + sf1-sf2;
|
||||||
|
}
|
||||||
|
LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[j]->round,sfdiff);
|
||||||
|
if (sfdiff > sfdiff_max) {
|
||||||
|
prev_harq_pid = j;
|
||||||
|
prev_harq_round = DLSCH_ptr->harq_processes[j]->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 @@
|
|||||||
#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
|
|||||||
|
|
||||||
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
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
// 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];
|
||||||
|
|||||||
Reference in New Issue
Block a user