PUSCH Repetition confoiguration and combining
Functionalities Added: - Modify RAR message to use number of repetitions configuration added in last commit - Configure msg3 with number of repetitions - DCI configuration for repetitions - Repeat MAC UL config each SF for the number of repetitions - PHY combining of repeated SF Signed-off-by: Mohamed Gamal <mohammed.abdelkhalek.ext@orange.com>
This commit is contained in:
@@ -2022,6 +2022,11 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
|
|||||||
ulsch->ue_type = 0;
|
ulsch->ue_type = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if(ulsch_pdu->ulsch_pdu_rel13.repetition_number >1) // Fill the Harq process parameters in the first Rep only
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
|
//AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
|
||||||
if(ulsch->harq_processes[harq_pid]->nb_rb == 0){
|
if(ulsch->harq_processes[harq_pid]->nb_rb == 0){
|
||||||
LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id);
|
LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id);
|
||||||
@@ -2031,6 +2036,9 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu
|
|||||||
ulsch->harq_processes[harq_pid]->subframe = subframe;
|
ulsch->harq_processes[harq_pid]->subframe = subframe;
|
||||||
ulsch->harq_processes[harq_pid]->handled = 0;
|
ulsch->harq_processes[harq_pid]->handled = 0;
|
||||||
|
|
||||||
|
ulsch->harq_processes[harq_pid]->repetition_number = ulsch_pdu->ulsch_pdu_rel13.repetition_number ;
|
||||||
|
ulsch->harq_processes[harq_pid]->total_number_of_repetitions = ulsch_pdu->ulsch_pdu_rel13.total_number_of_repetitions ;
|
||||||
|
|
||||||
ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
|
ulsch->harq_processes[harq_pid]->first_rb = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
|
||||||
ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
|
ulsch->harq_processes[harq_pid]->nb_rb = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,12 @@ typedef struct {
|
|||||||
// int calibration_flag;
|
// int calibration_flag;
|
||||||
/// delta_TF for power control
|
/// delta_TF for power control
|
||||||
int32_t delta_TF;
|
int32_t delta_TF;
|
||||||
|
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||||
|
// PUSCH Repetition Number for the current SF
|
||||||
|
uint32_t repetition_number ;
|
||||||
|
// PUSCH Total number of repetitions
|
||||||
|
uint32_t total_number_of_repetitions;
|
||||||
|
#endif
|
||||||
} LTE_UL_eNB_HARQ_t;
|
} LTE_UL_eNB_HARQ_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -555,12 +555,18 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
|
|||||||
int G = ulsch_harq->G;
|
int G = ulsch_harq->G;
|
||||||
unsigned int E;
|
unsigned int E;
|
||||||
decoder_if_t *tc;
|
decoder_if_t *tc;
|
||||||
|
static int32_t pusch_rep_buffer[3*(6144+64)];
|
||||||
|
int max_Ncb;
|
||||||
|
|
||||||
if (llr8_flag == 0)
|
if (llr8_flag == 0)
|
||||||
tc = *decoder16;
|
tc = *decoder16;
|
||||||
else
|
else
|
||||||
tc = *decoder8;
|
tc = *decoder8;
|
||||||
|
|
||||||
|
if(ulsch_harq->repetition_number == 1){
|
||||||
|
memset(pusch_rep_buffer,0,(sizeof(int32_t)*3*(6144+64))) ; // reset the buffer every new repetitions
|
||||||
|
}
|
||||||
|
|
||||||
for (r=0; r<ulsch_harq->C; r++) {
|
for (r=0; r<ulsch_harq->C; r++) {
|
||||||
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
// printf("before subblock deinterleaving c[%d] = %p\n",r,ulsch_harq->c[r]);
|
||||||
// Get Turbo interleaver parameters
|
// Get Turbo interleaver parameters
|
||||||
@@ -594,7 +600,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
|
|||||||
0, //Uplink
|
0, //Uplink
|
||||||
1,
|
1,
|
||||||
ulsch_harq->rvidx,
|
ulsch_harq->rvidx,
|
||||||
(ulsch_harq->round==0)?1:0, // clear
|
(ulsch_harq->rvidx==0)?1:0, // clear
|
||||||
ulsch_harq->Qm,
|
ulsch_harq->Qm,
|
||||||
1,
|
1,
|
||||||
r,
|
r,
|
||||||
@@ -604,6 +610,27 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stop_meas(&eNB->ulsch_rate_unmatching_stats);
|
stop_meas(&eNB->ulsch_rate_unmatching_stats);
|
||||||
|
|
||||||
|
max_Ncb = 3*ulsch_harq->RTC[r]*32 ;
|
||||||
|
|
||||||
|
if(ulsch_harq->total_number_of_repetitions > 1)
|
||||||
|
{
|
||||||
|
if (ulsch_harq->rvidx==1)
|
||||||
|
{ // Store the result of HARQ combining in the last emtc repetitions of sequence 0,2,3,1
|
||||||
|
for (int nn=0;nn<max_Ncb;nn++)
|
||||||
|
{
|
||||||
|
pusch_rep_buffer[nn] += ulsch_harq->w[r][nn] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions)
|
||||||
|
{
|
||||||
|
for (int nn=0;nn<max_Ncb;nn++)
|
||||||
|
{
|
||||||
|
ulsch_harq->w[r][nn] = pusch_rep_buffer[nn] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r_offset += E;
|
r_offset += E;
|
||||||
start_meas(&eNB->ulsch_deinterleaving_stats);
|
start_meas(&eNB->ulsch_deinterleaving_stats);
|
||||||
sub_block_deinterleaving_turbo(4+Kr,
|
sub_block_deinterleaving_turbo(4+Kr,
|
||||||
|
|||||||
@@ -1158,6 +1158,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
const int subframe = proc->subframe_rx;
|
const int subframe = proc->subframe_rx;
|
||||||
const int frame = proc->frame_rx;
|
const int frame = proc->frame_rx;
|
||||||
uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
|
uint32_t harq_pid0 = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
|
||||||
|
int rvidx_tab[4] = {0,2,3,1};
|
||||||
|
|
||||||
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
|
||||||
ulsch = eNB->ulsch[i];
|
ulsch = eNB->ulsch[i];
|
||||||
@@ -1174,8 +1175,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
if ((ulsch) &&
|
if ((ulsch) &&
|
||||||
(ulsch->rnti>0) &&
|
(ulsch->rnti>0) &&
|
||||||
(ulsch_harq->status == ACTIVE) &&
|
(ulsch_harq->status == ACTIVE) &&
|
||||||
(ulsch_harq->frame == frame) &&
|
((ulsch_harq->frame == frame) || (ulsch_harq->repetition_number >1) ) &&
|
||||||
(ulsch_harq->subframe == subframe) &&
|
((ulsch_harq->subframe == subframe) || (ulsch_harq->repetition_number >1) ) &&
|
||||||
(ulsch_harq->handled == 0)) {
|
(ulsch_harq->handled == 0)) {
|
||||||
// UE has ULSCH scheduling
|
// UE has ULSCH scheduling
|
||||||
for (int rb=0;
|
for (int rb=0;
|
||||||
@@ -1232,6 +1233,10 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
ulsch_harq->cqi_crc_status,
|
ulsch_harq->cqi_crc_status,
|
||||||
ulsch_harq->O_ACK,
|
ulsch_harq->O_ACK,
|
||||||
eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max);
|
eNB->ulsch_decoding_stats.p_time, eNB->ulsch_decoding_stats.max);
|
||||||
|
if (ulsch_harq->repetition_number < ulsch_harq->total_number_of_repetitions){
|
||||||
|
ulsch_harq->rvidx = rvidx_tab[(ulsch_harq->repetition_number%4)] ; // Set the correct rvidx for the next emtc repetitions
|
||||||
|
ulsch_harq->repetition_number +=1 ; // Increment repetition_number for the next ULSCH allocation
|
||||||
|
}
|
||||||
//compute the expected ULSCH RX power (for the stats)
|
//compute the expected ULSCH RX power (for the stats)
|
||||||
ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
|
ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
|
||||||
|
|
||||||
@@ -1287,7 +1292,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
|
|||||||
*/
|
*/
|
||||||
ulsch_harq->handled = 1;
|
ulsch_harq->handled = 1;
|
||||||
} // ulsch in error
|
} // ulsch in error
|
||||||
else {
|
else if(ulsch_harq->repetition_number == ulsch_harq->total_number_of_repetitions){
|
||||||
fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
|
fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
|
||||||
fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC
|
fill_rx_indication(eNB,i,frame,subframe); // indicate SDU to MAC
|
||||||
ulsch_harq->status = SCH_IDLE;
|
ulsch_harq->status = SCH_IDLE;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
|
|
||||||
extern RAN_CONTEXT_t RC;
|
extern RAN_CONTEXT_t RC;
|
||||||
|
|
||||||
|
extern const uint8_t pusch_repetition_Table8_2_36213[3][4];
|
||||||
|
|
||||||
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
|
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ void
|
|||||||
add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
|
add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
|
||||||
sub_frame_t subframeP) {
|
sub_frame_t subframeP) {
|
||||||
eNB_MAC_INST *mac = RC.mac[module_idP];
|
eNB_MAC_INST *mac = RC.mac[module_idP];
|
||||||
|
eNB_RRC_INST *rrc = RC.rrc[module_idP];
|
||||||
COMMON_channels_t *cc = &mac->common_channels[CC_id];
|
COMMON_channels_t *cc = &mac->common_channels[CC_id];
|
||||||
uint8_t j;
|
uint8_t j;
|
||||||
nfapi_ul_config_request_t *ul_req;
|
nfapi_ul_config_request_t *ul_req;
|
||||||
@@ -108,6 +110,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
|
|||||||
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
|
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
|
||||||
uint8_t sf_ahead_dl;
|
uint8_t sf_ahead_dl;
|
||||||
uint8_t rvseq[4] = {0, 2, 3, 1};
|
uint8_t rvseq[4] = {0, 2, 3, 1};
|
||||||
|
uint8_t pusch_maxNumRepetitionCEmodeA_r13;
|
||||||
ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe];
|
ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe];
|
||||||
ul_req_body = &ul_req->ul_config_request_body;
|
ul_req_body = &ul_req->ul_config_request_body;
|
||||||
AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n",
|
AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n",
|
||||||
@@ -140,7 +143,13 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP,
|
|||||||
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb);
|
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb);
|
||||||
// Re13 fields
|
// Re13 fields
|
||||||
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1;
|
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1;
|
||||||
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1;
|
if (ra->rach_resource_type > 0) {
|
||||||
|
pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]);
|
||||||
|
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions= pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][ra->pusch_repetition_levels];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions=1;
|
||||||
|
}
|
||||||
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
|
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
|
||||||
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
|
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
|
||||||
ul_req_body->number_of_pdus++;
|
ul_req_body->number_of_pdus++;
|
||||||
@@ -238,6 +247,7 @@ void generate_Msg2(module_id_t module_idP,
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
eNB_MAC_INST *mac = RC.mac[module_idP];
|
eNB_MAC_INST *mac = RC.mac[module_idP];
|
||||||
|
eNB_RRC_INST *rrc = RC.rrc[module_idP];
|
||||||
COMMON_channels_t *cc = mac->common_channels;
|
COMMON_channels_t *cc = mac->common_channels;
|
||||||
uint8_t *vrb_map = NULL;
|
uint8_t *vrb_map = NULL;
|
||||||
int first_rb = 0;
|
int first_rb = 0;
|
||||||
@@ -250,6 +260,7 @@ void generate_Msg2(module_id_t module_idP,
|
|||||||
dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
|
dl_config_pdu = &dl_req_body->dl_config_pdu_list[dl_req_body->number_pdu];
|
||||||
N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
|
N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
|
||||||
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
|
||||||
|
uint8_t PUSCH_Rep_Level;
|
||||||
int rmax = 0;
|
int rmax = 0;
|
||||||
int rep = 0;
|
int rep = 0;
|
||||||
int reps = 0;
|
int reps = 0;
|
||||||
@@ -261,6 +272,13 @@ void generate_Msg2(module_id_t module_idP,
|
|||||||
uint16_t absSF = (10 * frameP) + subframeP;
|
uint16_t absSF = (10 * frameP) + subframeP;
|
||||||
uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;
|
uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe;
|
||||||
|
|
||||||
|
if (ra->rach_resource_type > 0) {
|
||||||
|
PUSCH_Rep_Level= *(rrc->configuration.pusch_repetitionLevelCEmodeA_r13[CC_idP]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSCH_Rep_Level= 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (absSF > absSF_Msg2) {
|
if (absSF > absSF_Msg2) {
|
||||||
return; // we're not ready yet
|
return; // we're not ready yet
|
||||||
}
|
}
|
||||||
@@ -402,6 +420,8 @@ void generate_Msg2(module_id_t module_idP,
|
|||||||
ra->msg2_mpdcch_repetition_cnt++;
|
ra->msg2_mpdcch_repetition_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ra->pusch_repetition_levels = PUSCH_Rep_Level;
|
||||||
|
|
||||||
if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) {
|
if((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) {
|
||||||
/* Program PDSCH */
|
/* Program PDSCH */
|
||||||
LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
|
LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : In generate_Msg2, Programming PDSCH\n",
|
||||||
@@ -1270,6 +1290,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
|
|||||||
UE_id = find_UE_id(module_idP, ra->rnti);
|
UE_id = find_UE_id(module_idP, ra->rnti);
|
||||||
DevAssert(UE_id != -1);
|
DevAssert(UE_id != -1);
|
||||||
mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
|
mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
|
||||||
|
mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels;
|
||||||
cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
|
cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,14 @@ uint8_t rb_table[34] = {
|
|||||||
81, 90, 96, 100 // 30-33
|
81, 90, 96, 100 // 30-33
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This table hold the possible number of MTC repetition for CE ModeA
|
||||||
|
const uint8_t pusch_repetition_Table8_2_36213[3][4]=
|
||||||
|
{
|
||||||
|
1 , 2 , 4 , 8 ,
|
||||||
|
1 , 4 , 8 , 16,
|
||||||
|
1 , 4 , 16, 32
|
||||||
|
};
|
||||||
|
|
||||||
extern mui_t rrc_eNB_mui;
|
extern mui_t rrc_eNB_mui;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -301,16 +309,22 @@ rx_sdu(const module_id_t enb_mod_idP,
|
|||||||
if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
|
if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
|
||||||
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
|
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
|
||||||
} else {
|
} else {
|
||||||
// first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!!
|
if (ra->rach_resource_type > 0) {
|
||||||
ra->msg3_round++;
|
cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // TODO: Currently we don't support retransmission of Msg3 ( If in error Cancel RA procedure and reattach)
|
||||||
/* Prepare handling of retransmission */
|
}
|
||||||
get_Msg3allocret(&mac->common_channels[CC_idP],
|
else
|
||||||
ra->Msg3_subframe,
|
{
|
||||||
ra->Msg3_frame,
|
// first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!!
|
||||||
&ra->Msg3_frame,
|
ra->msg3_round++;
|
||||||
&ra->Msg3_subframe);
|
/* Prepare handling of retransmission */
|
||||||
// prepare handling of retransmission
|
get_Msg3allocret(&mac->common_channels[CC_idP],
|
||||||
add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP);
|
ra->Msg3_subframe,
|
||||||
|
ra->Msg3_frame,
|
||||||
|
&ra->Msg3_frame,
|
||||||
|
&ra->Msg3_subframe);
|
||||||
|
// prepare handling of retransmission
|
||||||
|
add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: program NACK for PHICH? */
|
/* TODO: program NACK for PHICH? */
|
||||||
@@ -1958,23 +1972,25 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
|
|||||||
int tpc = 0;
|
int tpc = 0;
|
||||||
int cqi_req = 0;
|
int cqi_req = 0;
|
||||||
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
eNB_MAC_INST *eNB = RC.mac[module_idP];
|
||||||
|
eNB_RRC_INST *rrc = RC.rrc[module_idP];
|
||||||
COMMON_channels_t *cc = eNB->common_channels;
|
COMMON_channels_t *cc = eNB->common_channels;
|
||||||
UE_list_t *UE_list = &(eNB->UE_list);
|
UE_list_t *UE_list = &(eNB->UE_list);
|
||||||
UE_TEMPLATE *UE_template = NULL;
|
UE_TEMPLATE *UE_template = NULL;
|
||||||
UE_sched_ctrl_t *UE_sched_ctrl = NULL;
|
UE_sched_ctrl_t *UE_sched_ctrl = NULL;
|
||||||
|
uint8_t Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13;
|
||||||
|
uint8_t UL_Scheduling_DCI_SF,UL_Scheduling_DCI_Frame_Even_Odd_Flag; //TODO: To be removed after scheduler relaxation Task
|
||||||
|
|
||||||
if (sched_subframeP < subframeP) {
|
if (sched_subframeP < subframeP) {
|
||||||
sched_frame++;
|
sched_frame++;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body);
|
nfapi_hi_dci0_request_body_t *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body);
|
||||||
|
nfapi_hi_dci0_request_body_t *hi_dci0_req_Rep;
|
||||||
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL;
|
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = NULL;
|
||||||
nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body);
|
nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body);
|
||||||
|
nfapi_ul_config_request_body_t *ul_req_body_Rep;
|
||||||
/* If frameP odd don't schedule */
|
nfapi_ul_config_request_pdu_t *ul_config_pdu;
|
||||||
if ((frameP & 1) == 1) {
|
nfapi_ul_config_request_pdu_t *ul_config_pdu_Rep;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop over all active UEs */
|
/* Loop over all active UEs */
|
||||||
for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
|
for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
|
||||||
@@ -2032,8 +2048,18 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
|
|||||||
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer;
|
RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer;
|
||||||
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer);
|
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer);
|
||||||
|
|
||||||
|
pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]);
|
||||||
|
Total_Num_Rep_ULSCH = pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][UE_template->pusch_repetition_levels];
|
||||||
|
UL_Scheduling_DCI_SF = (40-4 - Total_Num_Rep_ULSCH)%10; //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
|
||||||
|
UL_Scheduling_DCI_Frame_Even_Odd_Flag= ! (((40-4 - Total_Num_Rep_ULSCH)/10 )%2); //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
|
||||||
|
|
||||||
|
/* If frameP odd don't schedule */
|
||||||
|
if ((frameP&1) == UL_Scheduling_DCI_Frame_Even_Odd_Flag) //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
//if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) {
|
//if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) {
|
||||||
if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == 5)) {
|
if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == UL_Scheduling_DCI_SF)) {
|
||||||
/*
|
/*
|
||||||
* if there is information on bsr of DCCH, DTCH,
|
* if there is information on bsr of DCCH, DTCH,
|
||||||
* or if there is UL_SR,
|
* or if there is UL_SR,
|
||||||
@@ -2184,7 +2210,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
|
|||||||
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
|
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
|
||||||
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
|
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
|
||||||
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3
|
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB = 3
|
||||||
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
|
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = UE_template->pusch_repetition_levels;
|
||||||
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
|
AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
|
||||||
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
|
"epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
|
||||||
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
|
hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
|
||||||
@@ -2234,7 +2260,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
|
|||||||
);
|
);
|
||||||
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
|
fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
|
||||||
UE_template->rach_resource_type > 2 ? 2 : 1,
|
UE_template->rach_resource_type > 2 ? 2 : 1,
|
||||||
1, // total_number_of_repetitions
|
Total_Num_Rep_ULSCH, // total_number_of_repetitions
|
||||||
1, // repetition_number
|
1, // repetition_number
|
||||||
(frameP * 10) + subframeP);
|
(frameP * 10) + subframeP);
|
||||||
ul_req_tmp->number_of_pdus++;
|
ul_req_tmp->number_of_pdus++;
|
||||||
@@ -2363,6 +2389,27 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP,
|
|||||||
}
|
}
|
||||||
} // UE_is_to_be_scheduled
|
} // UE_is_to_be_scheduled
|
||||||
} // ULCCs
|
} // ULCCs
|
||||||
} // loop over UE_id
|
} // loop over UE_id
|
||||||
|
} // Schedule new ULSCH
|
||||||
|
|
||||||
|
// This section is to repeat ULSCH PDU for a number of MTC repetitions
|
||||||
|
for(int i=0;i<ul_req_tmp->number_of_pdus;i++)
|
||||||
|
{
|
||||||
|
ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[i];
|
||||||
|
if (ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) // Repeat ULSCH PDUs only
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
if(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number < ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions)
|
||||||
|
{
|
||||||
|
hi_dci0_req_Rep = &eNB->HI_DCI0_req[CC_id][(sched_subframeP+1)%10].hi_dci0_request_body;
|
||||||
|
ul_req_body_Rep = &eNB->UL_req_tmp[CC_id][(sched_subframeP+1)%10].ul_config_request_body;
|
||||||
|
ul_config_pdu_Rep = &ul_req_body_Rep->ul_config_pdu_list[ul_req_body_Rep->number_of_pdus];
|
||||||
|
// memset ((void *) ul_config_pdu_Rep, 0, sizeof (nfapi_ul_config_request_pdu_t));
|
||||||
|
memcpy ((void *) ul_config_pdu_Rep, ul_config_pdu, sizeof (nfapi_ul_config_request_pdu_t));
|
||||||
|
ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++;
|
||||||
|
ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel13.repetition_number = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number +1;
|
||||||
|
ul_req_body_Rep->number_of_pdus++;
|
||||||
|
} //repetition_number < total_number_of_repetitions
|
||||||
|
} // For loop on PDUs
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -921,6 +921,8 @@ typedef struct {
|
|||||||
uint8_t rach_resource_type;
|
uint8_t rach_resource_type;
|
||||||
uint16_t mpdcch_repetition_cnt;
|
uint16_t mpdcch_repetition_cnt;
|
||||||
frame_t Msg2_frame;
|
frame_t Msg2_frame;
|
||||||
|
/// Repetition column in pusch_repetition Table 8.2.b in TS36.213
|
||||||
|
uint8_t pusch_repetition_levels;
|
||||||
#endif
|
#endif
|
||||||
sub_frame_t Msg2_subframe;
|
sub_frame_t Msg2_subframe;
|
||||||
|
|
||||||
@@ -1133,6 +1135,8 @@ typedef struct {
|
|||||||
uint8_t msg2_narrowband;
|
uint8_t msg2_narrowband;
|
||||||
uint8_t msg34_narrowband;
|
uint8_t msg34_narrowband;
|
||||||
int msg4_rrc_sdu_length;
|
int msg4_rrc_sdu_length;
|
||||||
|
/// Repetition column in pusch_repetition Table 8.2.b in TS36.213
|
||||||
|
uint8_t pusch_repetition_levels;
|
||||||
#endif
|
#endif
|
||||||
int32_t crnti_rrc_mui;
|
int32_t crnti_rrc_mui;
|
||||||
int8_t crnti_harq_pid;
|
int8_t crnti_harq_pid;
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
|
|||||||
uint8_t *rar = (uint8_t *)(dlsch_buffer + 1);
|
uint8_t *rar = (uint8_t *)(dlsch_buffer + 1);
|
||||||
|
|
||||||
uint32_t rballoc = 0;
|
uint32_t rballoc = 0;
|
||||||
uint32_t reps = 0;
|
|
||||||
uint32_t ULdelay = 0;
|
uint32_t ULdelay = 0;
|
||||||
uint32_t cqireq = 0;
|
uint32_t cqireq = 0;
|
||||||
uint32_t mpdcch_nb_index = 0;
|
uint32_t mpdcch_nb_index = 0;
|
||||||
@@ -159,7 +158,6 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
|
|||||||
N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth);
|
N_NB_index = get_numnarrowbandbits(cc->mib->message.dl_Bandwidth);
|
||||||
|
|
||||||
/* UL Grant */
|
/* UL Grant */
|
||||||
reps = 0;
|
|
||||||
ra->msg3_mcs = 7;
|
ra->msg3_mcs = 7;
|
||||||
TPC = 3; // no power increase
|
TPC = 3; // no power increase
|
||||||
ULdelay = 0;
|
ULdelay = 0;
|
||||||
@@ -170,7 +168,7 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
|
|||||||
uint32_t buffer = 0;
|
uint32_t buffer = 0;
|
||||||
buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index));
|
buffer |= ra->msg34_narrowband << (16 + (4 - N_NB_index));
|
||||||
buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index)));
|
buffer |= ((rballoc & 0x0F) << (12 + (4 - N_NB_index)));
|
||||||
buffer |= ((reps & 0x03) << (10 + (4 - N_NB_index)));
|
buffer |= ((ra->pusch_repetition_levels & 0x03) << (10 + (4 - N_NB_index)));
|
||||||
buffer |= ((ra->msg3_mcs & 0x07) << (7 + (4 - N_NB_index)));
|
buffer |= ((ra->msg3_mcs & 0x07) << (7 + (4 - N_NB_index)));
|
||||||
buffer |= ((TPC & 0x07) << (4 + (4 - N_NB_index)));
|
buffer |= ((TPC & 0x07) << (4 + (4 - N_NB_index)));
|
||||||
buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index)));
|
buffer |= ((cqireq & 0x01) << (3 + (4 - N_NB_index)));
|
||||||
|
|||||||
Reference in New Issue
Block a user