Merge branch 'develop' into 'fix_do_ra_data'
# Conflicts: # openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c # openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
This commit is contained in:
@@ -122,6 +122,8 @@ typedef struct x2ap_register_enb_req_s {
|
||||
* CC Params
|
||||
*/
|
||||
int16_t eutra_band[MAX_NUM_CCs];
|
||||
int32_t nr_band[MAX_NUM_CCs];
|
||||
int32_t nrARFCN[MAX_NUM_CCs];
|
||||
uint32_t downlink_frequency[MAX_NUM_CCs];
|
||||
int32_t uplink_frequency_offset[MAX_NUM_CCs];
|
||||
uint32_t Nid_cell[MAX_NUM_CCs];
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "common/utils/LOG/log_extern.h"
|
||||
#include "assertions.h"
|
||||
#include "gnb_config.h"
|
||||
#include "gnb_paramdef.h"
|
||||
#include "UTIL/OTG/otg.h"
|
||||
#include "UTIL/OTG/otg_externs.h"
|
||||
#include "intertask_interface.h"
|
||||
@@ -232,8 +233,8 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
|
||||
scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] |= curr_bit<<i;
|
||||
}
|
||||
}else if(ssbmaplen==NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap){
|
||||
scc->ssb_PositionsInBurst->choice.mediumBitmap.size = 1;
|
||||
scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0;
|
||||
scc->ssb_PositionsInBurst->choice.mediumBitmap.size = 1;
|
||||
scc->ssb_PositionsInBurst->choice.mediumBitmap.bits_unused = 0;
|
||||
scc->ssb_PositionsInBurst->choice.mediumBitmap.buf = CALLOC(1,1);
|
||||
scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0] = 0;
|
||||
for (int i=0; i<8; i++)
|
||||
@@ -243,10 +244,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) {
|
||||
scc->ssb_PositionsInBurst->choice.longBitmap.bits_unused = 0;
|
||||
scc->ssb_PositionsInBurst->choice.longBitmap.buf = CALLOC(1,8);
|
||||
for (int j=0; j<8; j++) {
|
||||
scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] = 0;
|
||||
scc->ssb_PositionsInBurst->choice.longBitmap.buf[j] = 0;
|
||||
curr_bit = (ssbmap>>(j<<3))&(0xff);
|
||||
for (int i=0; i<8; i++)
|
||||
scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-j] |= (((curr_bit>>(7-i))&0x01)<<i);
|
||||
scc->ssb_PositionsInBurst->choice.longBitmap.buf[j] |= (((curr_bit>>(7-i))&0x01)<<i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1031,27 +1032,32 @@ void NRRCConfig(void) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
int J, l;
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
|
||||
//int num_gnbs = 0;
|
||||
//int num_component_carriers = 0;
|
||||
int j,k = 0;
|
||||
int32_t gnb_id = 0;
|
||||
|
||||
paramdef_t GNBSParams[] = GNBSPARAMS_DESC;
|
||||
////////// Identification parameters
|
||||
paramdef_t GNBParams[] = GNBPARAMS_DESC;
|
||||
paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0};
|
||||
/* get global parameters, defined outside any section in the config file */
|
||||
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
|
||||
|
||||
//paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
|
||||
NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t));
|
||||
uint64_t ssb_bitmap=0xff;
|
||||
memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t));
|
||||
prepare_scc(scc);
|
||||
paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc);
|
||||
paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0};
|
||||
|
||||
AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt,
|
||||
"Failed to parse config file %s, %uth attribute %s \n",
|
||||
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
|
||||
RC.config_file_name, i, GNB_CONFIG_STRING_ACTIVE_GNBS);
|
||||
|
||||
if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) {
|
||||
// Output a list of all gNBs.
|
||||
@@ -1121,19 +1127,28 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
|
||||
X2AP_REGISTER_ENB_REQ(msg_p).mnc);
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = 1;
|
||||
J = 0;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = 78; //ccparams_nr_x2.nr_band; //78
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = 3600000000; //ccparams_nr_x2.downlink_frequency; //3600000000
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = 0; //(unsigned int) ccparams_nr_x2.uplink_frequency_offset; //0
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= 0; //ccparams_nr_x2.Nid_cell; //0
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= 106; //ccparams_nr_x2.N_RB_DL; //106
|
||||
sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0);
|
||||
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
|
||||
|
||||
//Temp out
|
||||
/*X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);*/
|
||||
config_getlist(&SCCsParamList, NULL, 0, aprefix);
|
||||
if (SCCsParamList.numelt > 0) {
|
||||
sprintf(aprefix, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST,0,GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, 0);
|
||||
config_get( SCCsParams,sizeof(SCCsParams)/sizeof(paramdef_t),aprefix);
|
||||
fix_scc(scc,ssb_bitmap);
|
||||
}
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).num_cc = SCCsParamList.numelt;
|
||||
for (J = 0; J < SCCsParamList.numelt ; J++) {
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).nr_band[J] = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; //nr_band; //78
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).nrARFCN[J] = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier; //0
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= *scc->physCellId; //0
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;//106
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
|
||||
LOG_I(X2AP, "gNB configuration parameters: nr_band: %d, nr_ARFCN: %d, DL_RBs: %d, num_cc: %d \n",
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).nr_band[J],
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).nrARFCN[J],
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J],
|
||||
X2AP_REGISTER_ENB_REQ (msg_p).num_cc);
|
||||
}
|
||||
|
||||
sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k);
|
||||
config_getlist( &X2ParamList,X2Params,sizeof(X2Params)/sizeof(paramdef_t),aprefix);
|
||||
@@ -1222,4 +1237,3 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ typedef enum {
|
||||
/* global parameters, not under a specific section */
|
||||
#define GNB_CONFIG_STRING_ASN1_VERBOSITY "Asn1_verbosity"
|
||||
#define GNB_CONFIG_STRING_ACTIVE_GNBS "Active_gNBs"
|
||||
#define GNB_CONFIG_PUSCH_THREADS "Num_Threads_PUSCH"
|
||||
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* global configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
@@ -91,6 +92,11 @@ typedef enum {
|
||||
{GNB_CONFIG_STRING_ASN1_VERBOSITY, NULL, 0, uptr:NULL, defstrval:GNB_CONFIG_STRING_ASN1_VERBOSITY_NONE, TYPE_STRING, 0}, \
|
||||
{GNB_CONFIG_STRING_ACTIVE_GNBS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRINGLIST, 0} \
|
||||
}
|
||||
|
||||
#define NUM_THREADS_DESC { \
|
||||
{GNB_CONFIG_PUSCH_THREADS, NULL, 0, uptr:&num_threads_pusch, defuintval:1, TYPE_UINT, 0} \
|
||||
}
|
||||
|
||||
#define GNB_ASN1_VERBOSITY_IDX 0
|
||||
#define GNB_ACTIVE_GNBS_IDX 1
|
||||
|
||||
@@ -118,30 +124,6 @@ typedef enum {
|
||||
#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10"
|
||||
#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10"
|
||||
|
||||
|
||||
typedef struct ccparams_nr_x2 {
|
||||
char *frame_type;
|
||||
int32_t tdd_config;
|
||||
int32_t tdd_config_s;
|
||||
int32_t nr_band;
|
||||
long long int downlink_frequency;
|
||||
int32_t uplink_frequency_offset;
|
||||
int32_t Nid_cell;
|
||||
int32_t N_RB_DL;
|
||||
} ccparams_nr_x2_t;
|
||||
|
||||
|
||||
#define CCPARAMS_NR_X2_DESC(ccparams) { \
|
||||
{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&ccparams.frame_type, defstrval:"TDD", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&ccparams.tdd_config, defintval:3, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:&ccparams.tdd_config_s, defintval:0, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:&ccparams.nr_band, defintval:78, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:(int64_t *)&ccparams.downlink_frequency, defint64val:3600000000, TYPE_UINT64, 0}, \
|
||||
{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:&ccparams.uplink_frequency_offset, defintval:0, TYPE_INT, 0}, \
|
||||
{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:&ccparams.Nid_cell, defintval:0, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:&ccparams.N_RB_DL, defintval:106, TYPE_UINT, 0} \
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* cell configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
|
||||
@@ -914,7 +914,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
|
||||
#if (!defined(PRE_SCD_THREAD))
|
||||
if (!NODE_IS_DU(RC.rrc[module_idP]->node_type)) {
|
||||
void rlc_tick(int, int);
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP);
|
||||
rlc_tick(frameP, subframeP);
|
||||
pdcp_run(&ctxt);
|
||||
pdcp_mbms_run(&ctxt);
|
||||
rrc_rx_tx(&ctxt, CC_id);
|
||||
|
||||
@@ -182,7 +182,7 @@ rx_sdu(const module_id_t enb_mod_idP,
|
||||
UE_template_ptr->scheduled_ul_bytes = 0;
|
||||
}
|
||||
} else { // sduP == NULL => error
|
||||
LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
|
||||
LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x (len %d)\n",
|
||||
enb_mod_idP,
|
||||
harq_pid,
|
||||
CC_idP,
|
||||
|
||||
@@ -3099,6 +3099,9 @@ ue_scheduler(const module_id_t module_idP,
|
||||
}
|
||||
}
|
||||
|
||||
void rlc_tick(int, int);
|
||||
rlc_tick(rxFrameP % 1024, rxSubframeP);
|
||||
|
||||
//#endif
|
||||
UE_mac_inst[module_idP].txFrame = txFrameP;
|
||||
UE_mac_inst[module_idP].txSubframe = txSubframeP;
|
||||
|
||||
@@ -937,14 +937,22 @@ int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = {
|
||||
|
||||
|
||||
int get_format0(uint8_t index,
|
||||
uint8_t unpaired){
|
||||
uint8_t unpaired,
|
||||
frequency_range_t frequency_range){
|
||||
|
||||
uint16_t format;
|
||||
if (unpaired)
|
||||
format = table_6_3_3_2_3_prachConfig_Index[index][0];
|
||||
else
|
||||
format = table_6_3_3_2_2_prachConfig_Index[index][0];
|
||||
|
||||
if (unpaired) {
|
||||
if (frequency_range==FR1)
|
||||
format = table_6_3_3_2_3_prachConfig_Index[index][0];
|
||||
else
|
||||
format = table_6_3_3_2_4_prachConfig_Index[index][0];
|
||||
}
|
||||
else {
|
||||
if (frequency_range==FR1)
|
||||
format = table_6_3_3_2_2_prachConfig_Index[index][0];
|
||||
else
|
||||
AssertFatal(0==1,"no paired spectrum for FR2\n");
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
@@ -1402,11 +1410,12 @@ uint16_t table_63313[838] = {
|
||||
|
||||
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
|
||||
uint8_t nb_preambles,
|
||||
uint8_t unpaired) {
|
||||
uint8_t unpaired,
|
||||
frequency_range_t frequency_range) {
|
||||
|
||||
uint8_t config_index = rach_config->rach_ConfigGeneric.prach_ConfigurationIndex;
|
||||
uint8_t ncs_index = rach_config->rach_ConfigGeneric.zeroCorrelationZoneConfig;
|
||||
uint16_t format0 = get_format0(config_index, unpaired);
|
||||
uint16_t format0 = get_format0(config_index, unpaired, frequency_range);
|
||||
uint16_t NCS = get_NCS(ncs_index, format0, rach_config->restrictedSetConfig);
|
||||
uint16_t L_ra = (rach_config->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139) ? 139 : 839;
|
||||
uint16_t r,u,index,q,d_u,n_shift_ra,n_shift_ra_bar,d_start;
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
#define MAX_TDM (7) // Maximum nb of PRACH occasions TDMed in a slot
|
||||
#define MAX_FDM (8) // Maximum nb of PRACH occasions FDMed in a slot
|
||||
|
||||
typedef enum frequency_range_e {
|
||||
FR1 = 0,
|
||||
FR2
|
||||
} frequency_range_t;
|
||||
|
||||
// PRACH occasion details
|
||||
typedef struct prach_occasion_info {
|
||||
uint8_t start_symbol; // 0 - 13 (14 symbols in a slot)
|
||||
@@ -159,11 +164,12 @@ uint8_t get_pusch_mcs_table(long *mcs_Table,
|
||||
|
||||
uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
|
||||
uint8_t nb_preambles,
|
||||
uint8_t unpaired);
|
||||
uint8_t unpaired,
|
||||
frequency_range_t);
|
||||
|
||||
int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder);
|
||||
|
||||
int get_format0(uint8_t index, uint8_t unpaired);
|
||||
int get_format0(uint8_t index, uint8_t unpaired,frequency_range_t);
|
||||
|
||||
int64_t *get_prach_config_info(uint32_t pointa,
|
||||
uint8_t index,
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
|
||||
/*#include "PHY/defs_common.h"*/
|
||||
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
|
||||
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
|
||||
extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
|
||||
|
||||
@@ -147,7 +147,6 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
int i;
|
||||
lte_frame_type_t frame_type;
|
||||
|
||||
mac->phy_config.Mod_id = module_id;
|
||||
mac->phy_config.CC_id = cc_idP;
|
||||
@@ -201,6 +200,10 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
frequency_range_t frequency_range = band<100?FR1:FR2;
|
||||
|
||||
lte_frame_type_t frame_type;
|
||||
get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
|
||||
|
||||
// cell config
|
||||
@@ -236,8 +239,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask = 0;
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
|
||||
for (i=0; i<4; i++) {
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -310,7 +313,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
|
||||
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type);
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type,frequency_range);
|
||||
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ typedef struct {
|
||||
/// Random-access procedure flag
|
||||
uint8_t RA_active;
|
||||
/// Random-access window counter
|
||||
int8_t RA_window_cnt;
|
||||
int16_t RA_window_cnt;
|
||||
/// Random-access Msg3 size in bytes
|
||||
uint8_t RA_Msg3_size;
|
||||
/// Random-access prachMaskIndex
|
||||
@@ -292,10 +292,6 @@ typedef enum channel_bandwidth_e {
|
||||
bw_100MHz = 0x32
|
||||
} channel_bandwidth_t;
|
||||
|
||||
typedef enum frequency_range_e {
|
||||
FR1 = 0,
|
||||
FR2
|
||||
} frequency_range_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t identifier_dci_formats ; // 0 IDENTIFIER_DCI_FORMATS:
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
#include "assertions.h"
|
||||
#include "PHY/types.h"
|
||||
#include "PHY/defs_UE.h"
|
||||
#include "openair2/LAYER2/RLC/rlc.h"
|
||||
#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
#include "LAYER2/NR_MAC_UE/mac_proto.h"
|
||||
|
||||
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
|
||||
//extern uint8_t nfapi_mode;
|
||||
|
||||
|
||||
@@ -142,7 +142,6 @@ static ssb_list_info_t ssb_list;
|
||||
|
||||
extern int bwp_id;
|
||||
extern dci_pdu_rel15_t *def_dci_pdu_rel15;
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
|
||||
extern void mac_rlc_data_ind (
|
||||
const module_id_t module_idP,
|
||||
@@ -971,35 +970,30 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
uint16_t frame_number_4lsb = 0;
|
||||
for (int i=0; i<4; i++)
|
||||
frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
|
||||
//uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4]
|
||||
uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4]
|
||||
uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
|
||||
uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset;
|
||||
|
||||
//uint32_t ssb_index = 0; // TODO: ssb_index should obtain from L1 in case Lssb != 64
|
||||
|
||||
frame = frame << 4;
|
||||
frame = frame | frame_number_4lsb;
|
||||
|
||||
if(ssb_length == 64){
|
||||
ssb_index = ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] }
|
||||
for (int i=0; i<3; i++)
|
||||
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
|
||||
}else{
|
||||
if(ssb_subcarrier_offset_msb){
|
||||
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MIB
|
||||
LOG_I(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]);
|
||||
LOG_I(MAC,"system frame number(with LSB): %d\n", (int)frame);
|
||||
LOG_I(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon);
|
||||
LOG_I(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset);
|
||||
LOG_I(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position);
|
||||
LOG_I(MAC,"pdcch config sib1: %d\n", (int)mac->mib->pdcch_ConfigSIB1);
|
||||
LOG_I(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
|
||||
LOG_I(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
|
||||
LOG_I(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit);
|
||||
LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index);
|
||||
#endif
|
||||
LOG_D(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]);
|
||||
LOG_D(MAC,"system frame number(with LSB): %d\n", (int)frame);
|
||||
LOG_D(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon);
|
||||
LOG_D(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset);
|
||||
LOG_D(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position);
|
||||
LOG_D(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred);
|
||||
LOG_D(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection);
|
||||
LOG_D(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit);
|
||||
LOG_D(MAC,"ssb index(extra bits): %d\n", (int)ssb_index);
|
||||
|
||||
subcarrier_spacing_t scs_ssb = scs_30kHz; // default for
|
||||
//const uint32_t scs_index = 0;
|
||||
@@ -1022,8 +1016,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
int32_t num_rbs = -1;
|
||||
int32_t num_symbols = -1;
|
||||
int32_t rb_offset = -1;
|
||||
//LOG_I(MAC,"<<<<<<<<<configSIB1 %d index_4msb %d index_4lsb %d scs_ssb %d scs_pdcch %d switch %d ",
|
||||
//mac->mib->pdcch_ConfigSIB1,index_4msb,index_4lsb,scs_ssb,scs_pdcch, (scs_ssb << 5)|scs_pdcch);
|
||||
LOG_D(MAC,"<<<<<<<<<configSIB1: controlResourceSetZero %d searchSpaceZero %d scs_ssb %d scs_pdcch %d switch %d ",
|
||||
index_4msb,index_4lsb,scs_ssb,scs_pdcch, (scs_ssb << 5)|scs_pdcch);
|
||||
|
||||
// type0-pdcch coreset
|
||||
switch( (scs_ssb << 5)|scs_pdcch ){
|
||||
|
||||
@@ -124,6 +124,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
frequency_range_t frequency_range = band<100?FR1:FR2;
|
||||
|
||||
lte_frame_type_t frame_type;
|
||||
get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
|
||||
RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
|
||||
@@ -213,7 +216,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG;
|
||||
cfg->num_tlv++;
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,nb_preambles, frame_type);
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup,nb_preambles, frame_type, frequency_range);
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG;
|
||||
cfg->num_tlv++;
|
||||
cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = 1;
|
||||
@@ -252,8 +255,8 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = 0;
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0;
|
||||
for (i=0; i<4; i++) {
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i+4]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[i]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[0].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[3-i]<<i*8);
|
||||
cfg->ssb_table.ssb_mask_list[1].ssb_mask.value += (scc->ssb_PositionsInBurst->choice.longBitmap.buf[7-i]<<i*8);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -309,6 +312,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
|
||||
|
||||
|
||||
|
||||
extern uint16_t sl_ahead;
|
||||
int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
int pdsch_AntennaPorts,
|
||||
@@ -322,6 +326,30 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
if (scc != NULL ) {
|
||||
AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present);
|
||||
|
||||
/* dimension UL_tti_req_ahead for number of slots in frame */
|
||||
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
|
||||
const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
RC.nrmac[Mod_idP]->UL_tti_req_ahead[0] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t));
|
||||
AssertFatal(RC.nrmac[Mod_idP]->UL_tti_req_ahead[0],
|
||||
"could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n");
|
||||
/* fill in slot/frame numbers: slot is fixed, frame will be updated by
|
||||
* scheduler */
|
||||
for (int i = 0; i < n; ++i) {
|
||||
nfapi_nr_ul_tti_request_t *req = &RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][i];
|
||||
/* consider that scheduler runs sl_ahead: the first sl_ahead slots are
|
||||
* already "in the past" and thus we put frame 1 instead of 0! Note that
|
||||
* variable sl_ahead seems to not be correctly initialized, but I leave
|
||||
* it for information purposes here (the fix would always put 0, what
|
||||
* happens now, too) */
|
||||
req->SFN = i < sl_ahead;
|
||||
req->Slot = i;
|
||||
}
|
||||
|
||||
RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL =
|
||||
calloc(n * 275, sizeof(uint16_t));
|
||||
AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL,
|
||||
"could not allocate memory for RC.nrmac[]->common_channels[0].vrb_map_UL\n");
|
||||
|
||||
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
|
||||
|
||||
config_common(Mod_idP,
|
||||
@@ -369,6 +397,12 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
bwpList->list.count);
|
||||
const int bwp_id = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
|
||||
struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList =
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
|
||||
AssertFatal(ubwpList->list.count == 1,
|
||||
"uplinkBWP_ToAddModList has %d BWP!\n",
|
||||
ubwpList->list.count);
|
||||
UE_info->UE_sched_ctrl[UE_id].active_ubwp = ubwpList->list.array[bwp_id - 1];
|
||||
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
|
||||
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
|
||||
/* TODO: should check for free RA process */
|
||||
|
||||
@@ -32,9 +32,7 @@
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
#include "NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
#include "common/utils/LOG/log.h"
|
||||
@@ -51,15 +49,10 @@
|
||||
#include "openair1/PHY/defs_gNB.h"
|
||||
#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
|
||||
|
||||
//Agent-related headers
|
||||
#include "flexran_agent_extern.h"
|
||||
#include "flexran_agent_mac.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
|
||||
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
|
||||
|
||||
void clear_mac_stats(gNB_MAC_INST *gNB) {
|
||||
@@ -92,9 +85,12 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
int CC_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP){
|
||||
NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon;
|
||||
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0];
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req[0];
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
|
||||
&gNB->UL_tti_req_ahead[CC_idP][(slotP + num_slots - 1) % num_slots];
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0];
|
||||
nfapi_nr_tx_data_request_t *TX_req = &gNB->TX_req[0];
|
||||
|
||||
@@ -112,12 +108,17 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
UL_dci_req[CC_idP].Slot = slotP;
|
||||
UL_dci_req[CC_idP].numPdus = 0;
|
||||
|
||||
UL_tti_req[CC_idP].SFN = frameP;
|
||||
UL_tti_req[CC_idP].Slot = slotP;
|
||||
UL_tti_req[CC_idP].n_pdus = 0;
|
||||
UL_tti_req[CC_idP].n_ulsch = 0;
|
||||
UL_tti_req[CC_idP].n_ulcch = 0;
|
||||
UL_tti_req[CC_idP].n_group = 0;
|
||||
/* advance last round's future UL_tti_req to be ahead of current frame/slot */
|
||||
future_ul_tti_req->SFN = (slotP == 0 ? frameP : frameP + 1) % 1024;
|
||||
/* future_ul_tti_req->Slot is fixed! */
|
||||
future_ul_tti_req->n_pdus = 0;
|
||||
future_ul_tti_req->n_ulsch = 0;
|
||||
future_ul_tti_req->n_ulcch = 0;
|
||||
future_ul_tti_req->n_group = 0;
|
||||
|
||||
/* UL_tti_req is a simple pointer into the current UL_tti_req_ahead, i.e.,
|
||||
* it walks over UL_tti_req_ahead in a circular fashion */
|
||||
gNB->UL_tti_req[CC_idP] = &gNB->UL_tti_req_ahead[CC_idP][slotP];
|
||||
|
||||
TX_req[CC_idP].Number_of_PDUs = 0;
|
||||
|
||||
@@ -285,58 +286,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
{
|
||||
int CC_id;
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_idP];
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
|
||||
nfapi_ul_config_request_t *ul_req = &mac->UL_tti_req[CC_id];
|
||||
|
||||
*ul_req = *ul_req_tmp;
|
||||
|
||||
// Restore the pointer
|
||||
ul_req->ul_config_request_body.ul_config_pdu_list = ul_req_pdu;
|
||||
ul_req->sfn_sf = (frameP<<7) + slotP;
|
||||
ul_req_tmp->ul_config_request_body.number_of_pdus = 0;
|
||||
|
||||
if (ul_req->ul_config_request_body.number_of_pdus>0)
|
||||
{
|
||||
LOG_D(PHY, "%s() active NOW (frameP:%d slotP:%d) pdus:%d\n", __FUNCTION__, frameP, slotP, ul_req->ul_config_request_body.number_of_pdus);
|
||||
}
|
||||
|
||||
memcpy((void*)ul_req->ul_config_request_body.ul_config_pdu_list,
|
||||
(void*)ul_req_tmp->ul_config_request_body.ul_config_pdu_list,
|
||||
ul_req->ul_config_request_body.number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void nr_schedule_pusch(int Mod_idP,
|
||||
int UE_id,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP) {
|
||||
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
int k = slotP + ul_slots - num_slots_per_tdd;
|
||||
NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k];
|
||||
if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) {
|
||||
UL_tti_req->SFN = pusch->frame;
|
||||
UL_tti_req->Slot = pusch->slot;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu;
|
||||
UL_tti_req->n_pdus+=1;
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0, sizeof(NR_sched_pusch));
|
||||
}
|
||||
}
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
return (bitmap >> slot) & 0x01;
|
||||
}
|
||||
@@ -355,7 +304,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_COMMON_channels_t *cc = gNB->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
|
||||
@@ -397,7 +345,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
|
||||
}
|
||||
|
||||
int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
|
||||
int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
|
||||
|
||||
const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
|
||||
|
||||
@@ -424,7 +372,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
|
||||
// clear vrb_maps
|
||||
memset(cc[CC_id].vrb_map, 0, sizeof(uint16_t) * 275);
|
||||
memset(cc[CC_id].vrb_map_UL, 0, sizeof(uint16_t) * 275);
|
||||
// clear last scheduled slot's content (only)!
|
||||
const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const int last_slot = (slot + num_slots - 1) % num_slots;
|
||||
uint16_t *vrb_map_UL = cc[CC_id].vrb_map_UL;
|
||||
memset(&vrb_map_UL[last_slot * 275], 0, sizeof(uint16_t) * 275);
|
||||
|
||||
clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot);
|
||||
}
|
||||
@@ -434,44 +386,43 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
|
||||
|
||||
// This schedules MIB
|
||||
schedule_nr_mib(module_idP, frame, slot, slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
|
||||
// This schedule PRACH if we are not in phy_test mode
|
||||
if (get_softmodem_params()->phy_test == 0)
|
||||
schedule_nr_prach(module_idP, frame, slot);
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
/* we need to make sure that resources for PRACH are free. To avoid that
|
||||
e.g. PUSCH has already been scheduled, make sure we schedule before
|
||||
anything else: below, we simply assume an advance one frame (minus one
|
||||
slot, because otherwise we would allocate the current slot in
|
||||
UL_tti_req_ahead), but be aware that, e.g., K2 is allowed to be larger
|
||||
(schedule_nr_prach will assert if resources are not free). */
|
||||
const sub_frame_t n_slots_ahead = nr_slots_per_frame[*scc->ssbSubcarrierSpacing] - 1;
|
||||
const frame_t f = (frame + (slot + n_slots_ahead) / nr_slots_per_frame[*scc->ssbSubcarrierSpacing]) % 1024;
|
||||
const sub_frame_t s = (slot + n_slots_ahead) % nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
schedule_nr_prach(module_idP, f, s);
|
||||
}
|
||||
|
||||
// This schedule SR
|
||||
// TODO
|
||||
|
||||
// This schedule CSI measurement reporting
|
||||
if (UE_info->active[UE_id])
|
||||
nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
nr_csi_meas_reporting(module_idP, UE_id, frame, slot, num_slots_per_tdd, nr_ulmix_slots, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
|
||||
// This schedule RA procedure if not in phy_test mode
|
||||
// Otherwise already consider 5G already connected
|
||||
RC.nrmac[module_idP]->current_slot=slot;
|
||||
if (get_softmodem_params()->phy_test == 0) {
|
||||
nr_schedule_RA(module_idP, frame, slot);
|
||||
nr_schedule_reception_msg3(module_idP, 0, frame, slot);
|
||||
}
|
||||
|
||||
// This schedules the DCI for Uplink and subsequently PUSCH
|
||||
|
||||
// The decision about whether to schedule is done for each UE independently
|
||||
// inside
|
||||
if (UE_info->active[UE_id] && slot < 10) {
|
||||
|
||||
int tda = 1; // time domain assignment hardcoded for now
|
||||
schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap);
|
||||
nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot);
|
||||
if (slot < 10) {
|
||||
nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap);
|
||||
}
|
||||
|
||||
|
||||
if (UE_info->active[UE_id]
|
||||
&& (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd))
|
||||
// This schedules the DCI for Downlink and PDSCH
|
||||
if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd)
|
||||
&& slot < 10) {
|
||||
|
||||
ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd;
|
||||
nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
extern const uint8_t nr_slots_per_frame[5];
|
||||
extern uint16_t sl_ahead;
|
||||
|
||||
uint8_t DELTA[4]= {2,3,4,6};
|
||||
|
||||
@@ -62,19 +63,19 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
|
||||
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
|
||||
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
|
||||
uint8_t total_RApreambles = 64;
|
||||
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
|
||||
uint8_t total_RApreambles = 64;
|
||||
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
|
||||
total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
|
||||
|
||||
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
|
||||
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
|
||||
uint16_t start_symbol_index = 0;
|
||||
uint8_t mu,N_dur=0,N_t_slot=0,start_symbol = 0, temp_start_symbol = 0, N_RA_slot=0;
|
||||
uint16_t format,RA_sfn_index = -1;
|
||||
uint8_t config_period = 1;
|
||||
uint8_t config_period = 1;
|
||||
uint16_t prach_occasion_id = -1;
|
||||
uint8_t num_active_ssb = cc->num_active_ssb;
|
||||
uint8_t num_active_ssb = cc->num_active_ssb;
|
||||
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
|
||||
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
|
||||
@@ -95,45 +96,51 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
|
||||
&N_RA_slot,
|
||||
&config_period);
|
||||
uint8_t index = 0,slot_index = 0;
|
||||
for (slot_index = 0;slot_index < N_RA_slot; slot_index++) {
|
||||
for (slot_index = 0;slot_index < N_RA_slot; slot_index++) {
|
||||
if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
|
||||
if((mu == 1) || (mu == 3))
|
||||
slot_index = 1; //For scs = 30khz and 120khz
|
||||
}
|
||||
for (int i=0; i< N_t_slot; i++) {
|
||||
temp_start_symbol = (start_symbol + i * N_dur + 14 * slot_index) % 14;
|
||||
if(symbol == temp_start_symbol) {
|
||||
start_symbol_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(symbol == temp_start_symbol) {
|
||||
start_symbol_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
|
||||
if((mu == 1) || (mu == 3))
|
||||
slot_index = 0; //For scs = 30khz and 120khz
|
||||
}
|
||||
|
||||
// prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index;
|
||||
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period)*cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index;
|
||||
//one RO is shared by one or more SSB
|
||||
if(num_ssb_per_RO <= 1 )
|
||||
index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb;
|
||||
//one SSB have more than one continuous RO
|
||||
else if ( num_ssb_per_RO > 1) {
|
||||
index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ;
|
||||
for(int j = 0;j < num_ssb_per_RO;j++) {
|
||||
if(preamble_index < (((j+1) * total_RApreambles) / num_ssb_per_RO))
|
||||
index = index + j;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n", frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
|
||||
// prach_occasion_id = subframe_index * N_t_slot * N_RA_slot * fdm + N_RA_slot_index * N_t_slot * fdm + freq_index + fdm * start_symbol_index;
|
||||
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period)*cc->total_prach_occasions_per_config_period) +
|
||||
(RA_sfn_index + slot_index) * N_t_slot * fdm + start_symbol_index * fdm + freq_index;
|
||||
|
||||
//one RO is shared by one or more SSB
|
||||
if(num_ssb_per_RO <= 1 )
|
||||
index = (int) (prach_occasion_id / (int)(1/num_ssb_per_RO)) % num_active_ssb;
|
||||
//one SSB have more than one continuous RO
|
||||
else if ( num_ssb_per_RO > 1) {
|
||||
index = (prach_occasion_id * (int)num_ssb_per_RO)% num_active_ssb ;
|
||||
for(int j = 0;j < num_ssb_per_RO;j++) {
|
||||
if(preamble_index < (((j+1) * total_RApreambles) / num_ssb_per_RO))
|
||||
index = index + j;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n",
|
||||
frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
//Compute Total active SSBs and RO available
|
||||
void find_SSB_and_RO_available(module_id_t module_idP) {
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc = &gNB->common_channels[0];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
@@ -141,7 +148,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
|
||||
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
|
||||
uint8_t mu,N_dur=0,N_t_slot=0,start_symbol=0,N_RA_slot = 0;
|
||||
uint16_t format,N_RA_sfn = 0,unused_RA_occasion,repetition = 0;
|
||||
uint8_t num_active_ssb = 0;
|
||||
uint8_t num_active_ssb = 0;
|
||||
uint8_t max_association_period = 1;
|
||||
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
|
||||
@@ -151,190 +158,190 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
|
||||
|
||||
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
|
||||
get_nr_prach_occasion_info_from_index(config_index,
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
|
||||
mu,
|
||||
cc->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&N_RA_slot,
|
||||
&N_RA_sfn,
|
||||
&max_association_period);
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
|
||||
mu,
|
||||
cc->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&N_RA_slot,
|
||||
&N_RA_sfn,
|
||||
&max_association_period);
|
||||
|
||||
float num_ssb_per_RO = ssb_per_rach_occasion[cfg->prach_config.ssb_per_rach.value];
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
uint64_t L_ssb = (((uint64_t) cfg->ssb_table.ssb_mask_list[0].ssb_mask.value)<<32) | cfg->ssb_table.ssb_mask_list[1].ssb_mask.value ;
|
||||
uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm;
|
||||
uint32_t total_RA_occasions = N_RA_sfn * N_t_slot * N_RA_slot * fdm;
|
||||
|
||||
for(int i = 0;i < 64;i++) {
|
||||
for(int i = 0;i < 64;i++) {
|
||||
if ((L_ssb >> (63-i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1
|
||||
cc->ssb_index[num_active_ssb] = i;
|
||||
num_active_ssb++;
|
||||
num_active_ssb++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
|
||||
for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
|
||||
if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
|
||||
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
total_RA_occasions = total_RA_occasions * i;
|
||||
cc->max_association_period = i;
|
||||
}
|
||||
}
|
||||
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
total_RA_occasions = total_RA_occasions * i;
|
||||
cc->max_association_period = i;
|
||||
}
|
||||
}
|
||||
if(cc->max_association_period == 0)
|
||||
cc->max_association_period = 1;
|
||||
cc->max_association_period = 1;
|
||||
|
||||
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
|
||||
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
|
||||
cc->num_active_ssb = num_active_ssb;
|
||||
|
||||
LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n", cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
|
||||
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
|
||||
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
|
||||
cc->num_active_ssb = num_active_ssb;
|
||||
|
||||
LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n",
|
||||
cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
|
||||
}
|
||||
|
||||
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
|
||||
|
||||
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
{
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc = gNB->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0];
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP];
|
||||
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
|
||||
if (is_nr_UL_slot(scc,slotP)) {
|
||||
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
|
||||
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
|
||||
uint16_t RA_sfn_index = -1;
|
||||
uint8_t config_period = 1;
|
||||
uint16_t format;
|
||||
int slot_index = 0;
|
||||
uint16_t prach_occasion_id = -1;
|
||||
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
|
||||
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
|
||||
uint16_t RA_sfn_index = -1;
|
||||
uint8_t config_period = 1;
|
||||
uint16_t format;
|
||||
int slot_index = 0;
|
||||
uint16_t prach_occasion_id = -1;
|
||||
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
|
||||
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
|
||||
else
|
||||
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
|
||||
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
|
||||
else
|
||||
mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
|
||||
if ( get_nr_prach_info_from_index(config_index,
|
||||
(int)frameP,
|
||||
(int)slotP,
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
|
||||
mu,
|
||||
cc->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&RA_sfn_index,
|
||||
&N_RA_slot,
|
||||
&config_period) ) {
|
||||
uint16_t format0 = format&0xff; // first column of format from table
|
||||
uint16_t format1 = (format>>8)&0xff; // second column of format from table
|
||||
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
|
||||
// prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4
|
||||
if ( get_nr_prach_info_from_index(config_index,
|
||||
(int)frameP,
|
||||
(int)slotP,
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
|
||||
mu,
|
||||
cc->frame_type,
|
||||
&format,
|
||||
&start_symbol,
|
||||
&N_t_slot,
|
||||
&N_dur,
|
||||
&RA_sfn_index,
|
||||
&N_RA_slot,
|
||||
&config_period) ) {
|
||||
|
||||
if (N_RA_slot > 1) { //more than 1 PRACH slot in a subframe
|
||||
if (slotP%2 == 1){
|
||||
slot_index = 1;
|
||||
}
|
||||
else {
|
||||
slot_index = 0;
|
||||
}
|
||||
}else if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
|
||||
slot_index = 0;
|
||||
}
|
||||
uint16_t format0 = format&0xff; // first column of format from table
|
||||
uint16_t format1 = (format>>8)&0xff; // second column of format from table
|
||||
|
||||
if (N_RA_slot > 1) { //more than 1 PRACH slot in a subframe
|
||||
if (slotP%2 == 1)
|
||||
slot_index = 1;
|
||||
else
|
||||
slot_index = 0;
|
||||
}else if (N_RA_slot <= 1) { //1 PRACH slot in a subframe
|
||||
slot_index = 0;
|
||||
}
|
||||
|
||||
UL_tti_req->SFN = frameP;
|
||||
UL_tti_req->Slot = slotP;
|
||||
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
|
||||
for (int td_index=0; td_index<N_t_slot; td_index++) {
|
||||
UL_tti_req->SFN = frameP;
|
||||
UL_tti_req->Slot = slotP;
|
||||
for (int fdm_index=0; fdm_index < fdm; fdm_index++) { // one structure per frequency domain occasion
|
||||
for (int td_index=0; td_index<N_t_slot; td_index++) {
|
||||
|
||||
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) + (RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
|
||||
if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
|
||||
prach_occasion_id = (((frameP % (cc->max_association_period * config_period))/config_period) * cc->total_prach_occasions_per_config_period) +
|
||||
(RA_sfn_index + slot_index) * N_t_slot * fdm + td_index * fdm + fdm_index;
|
||||
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
|
||||
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
|
||||
UL_tti_req->n_pdus+=1;
|
||||
if((prach_occasion_id < cc->total_prach_occasions) && (td_index == 0)){
|
||||
|
||||
// filling the prach fapi structure
|
||||
prach_pdu->phys_cell_id = *scc->physCellId;
|
||||
prach_pdu->num_prach_ocas = N_t_slot;
|
||||
prach_pdu->prach_start_symbol = start_symbol;
|
||||
prach_pdu->num_ra = fdm_index;
|
||||
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
|
||||
format0,
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
|
||||
|
||||
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
|
||||
frameP, slotP,
|
||||
prach_occasion_id, prach_pdu->num_ra,
|
||||
prach_pdu->prach_start_symbol,
|
||||
slot_index, RA_sfn_index);
|
||||
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
|
||||
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
|
||||
if (format1!=0xff) {
|
||||
switch(format0) {
|
||||
case 0xa1:
|
||||
prach_pdu->prach_format = 11;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_pdu->prach_format = 12;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_pdu->prach_format = 13;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t);
|
||||
nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu;
|
||||
memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t));
|
||||
UL_tti_req->n_pdus+=1;
|
||||
|
||||
// filling the prach fapi structure
|
||||
prach_pdu->phys_cell_id = *scc->physCellId;
|
||||
prach_pdu->num_prach_ocas = N_t_slot;
|
||||
prach_pdu->prach_start_symbol = start_symbol;
|
||||
prach_pdu->num_ra = fdm_index;
|
||||
prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig,
|
||||
format0,
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
|
||||
|
||||
LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
|
||||
frameP, slotP,
|
||||
prach_occasion_id, prach_pdu->num_ra,
|
||||
prach_pdu->prach_start_symbol,
|
||||
slot_index, RA_sfn_index);
|
||||
// SCF PRACH PDU format field does not consider A1/B1 etc. possibilities
|
||||
// We added 9 = A1/B1 10 = A2/B2 11 A3/B3
|
||||
if (format1!=0xff) {
|
||||
switch(format0) {
|
||||
case 0xa1:
|
||||
prach_pdu->prach_format = 11;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_pdu->prach_format = 12;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_pdu->prach_format = 13;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format");
|
||||
}
|
||||
}
|
||||
else{
|
||||
switch(format0) {
|
||||
case 0:
|
||||
prach_pdu->prach_format = 0;
|
||||
break;
|
||||
case 1:
|
||||
prach_pdu->prach_format = 1;
|
||||
break;
|
||||
case 2:
|
||||
prach_pdu->prach_format = 2;
|
||||
break;
|
||||
case 3:
|
||||
prach_pdu->prach_format = 3;
|
||||
break;
|
||||
case 0xa1:
|
||||
prach_pdu->prach_format = 4;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_pdu->prach_format = 5;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_pdu->prach_format = 6;
|
||||
break;
|
||||
case 0xb1:
|
||||
prach_pdu->prach_format = 7;
|
||||
break;
|
||||
case 0xb4:
|
||||
prach_pdu->prach_format = 8;
|
||||
break;
|
||||
case 0xc0:
|
||||
prach_pdu->prach_format = 9;
|
||||
break;
|
||||
case 0xc2:
|
||||
prach_pdu->prach_format = 10;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid PRACH format");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
switch(format0) {
|
||||
case 0:
|
||||
prach_pdu->prach_format = 0;
|
||||
break;
|
||||
case 1:
|
||||
prach_pdu->prach_format = 1;
|
||||
break;
|
||||
case 2:
|
||||
prach_pdu->prach_format = 2;
|
||||
break;
|
||||
case 3:
|
||||
prach_pdu->prach_format = 3;
|
||||
break;
|
||||
case 0xa1:
|
||||
prach_pdu->prach_format = 4;
|
||||
break;
|
||||
case 0xa2:
|
||||
prach_pdu->prach_format = 5;
|
||||
break;
|
||||
case 0xa3:
|
||||
prach_pdu->prach_format = 6;
|
||||
break;
|
||||
case 0xb1:
|
||||
prach_pdu->prach_format = 7;
|
||||
break;
|
||||
case 0xb4:
|
||||
prach_pdu->prach_format = 8;
|
||||
break;
|
||||
case 0xc0:
|
||||
prach_pdu->prach_format = 9;
|
||||
break;
|
||||
case 0xc2:
|
||||
prach_pdu->prach_format = 10;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"Invalid PRACH format");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,7 +370,14 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
|
||||
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
|
||||
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
|
||||
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
|
||||
|
||||
|
||||
// we can't schedule msg2 before sl_ahead since prach
|
||||
int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
|
||||
if ((eff_slot-rach_slot)<=sl_ahead) {
|
||||
*msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
|
||||
*msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
|
||||
}
|
||||
|
||||
switch(response_window){
|
||||
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
|
||||
slot_window = 1;
|
||||
@@ -396,12 +410,11 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
|
||||
|
||||
// slot and frame limit to transmit msg2 according to response window
|
||||
uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu];
|
||||
//uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
|
||||
|
||||
uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1);
|
||||
|
||||
// go to previous slot if the current scheduled slot is beyond the response window
|
||||
// and if the slot is not among the PDCCH monitored ones (38.213 10.1)
|
||||
while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
|
||||
while (((*msg2_slot>slot_limit)&&(*msg2_frame>frame_limit)) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) {
|
||||
if((*msg2_slot%tdd_period_slot) > 0)
|
||||
(*msg2_slot)--;
|
||||
else
|
||||
@@ -562,7 +575,9 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
|
||||
stop_meas(&mac->schedule_ra);
|
||||
}
|
||||
|
||||
void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
|
||||
void nr_get_Msg3alloc(module_id_t module_id,
|
||||
int CC_id,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Uplink_t *ubwp,
|
||||
sub_frame_t current_slot,
|
||||
frame_t current_frame,
|
||||
@@ -596,27 +611,25 @@ void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
|
||||
ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
|
||||
|
||||
LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
|
||||
ra->msg3_nb_rb = 18;
|
||||
ra->msg3_first_rb = 0;
|
||||
}
|
||||
|
||||
|
||||
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_idP];
|
||||
nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0];
|
||||
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
|
||||
NR_RA_t *ra = &cc->ra[0];
|
||||
|
||||
if (ra->state == WAIT_Msg3) {
|
||||
if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot) ){
|
||||
ul_req->SFN = ra->Msg3_frame;
|
||||
ul_req->Slot = ra->Msg3_slot;
|
||||
ul_req->pdus_list[ul_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
|
||||
ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu;
|
||||
ul_req->n_pdus+=1;
|
||||
}
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * 275];
|
||||
const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
/* search 18 free RBs */
|
||||
int rbSize = 0;
|
||||
int rbStart = 0;
|
||||
while (rbSize < 18) {
|
||||
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
|
||||
rbSize = 0;
|
||||
while (rbStart < bwpSize && vrb_map_UL[rbStart])
|
||||
rbStart++;
|
||||
AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n");
|
||||
while (rbStart + rbSize < bwpSize
|
||||
&& !vrb_map_UL[rbStart + rbSize]
|
||||
&& rbSize < 18)
|
||||
rbSize++;
|
||||
}
|
||||
ra->msg3_nb_rb = 18;
|
||||
ra->msg3_first_rb = rbStart;
|
||||
}
|
||||
|
||||
void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
|
||||
@@ -631,10 +644,32 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * 275];
|
||||
for (int i = 0; i < ra->msg3_nb_rb; ++i) {
|
||||
AssertFatal(!vrb_map_UL[i + ra->msg3_first_rb],
|
||||
"RB %d in %4d.%2d is already taken, cannot allocate Msg3!\n",
|
||||
i + ra->msg3_first_rb,
|
||||
ra->Msg3_frame,
|
||||
ra->Msg3_slot);
|
||||
vrb_map_UL[i + ra->msg3_first_rb] = 1;
|
||||
}
|
||||
|
||||
LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
|
||||
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu;
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot];
|
||||
AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame
|
||||
&& future_ul_tti_req->Slot == ra->Msg3_slot,
|
||||
"future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
|
||||
future_ul_tti_req->SFN,
|
||||
future_ul_tti_req->Slot,
|
||||
ra->Msg3_frame,
|
||||
ra->Msg3_slot);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
|
||||
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
|
||||
AssertFatal(ra->secondaryCellGroup,
|
||||
"no secondaryCellGroup for RNTI %04x\n",
|
||||
@@ -913,7 +948,7 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
dl_req->nPDUs+=2;
|
||||
|
||||
// Program UL processing for Msg3
|
||||
nr_get_Msg3alloc(scc, ubwp, slotP, frameP, ra);
|
||||
nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
|
||||
LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
|
||||
nr_add_msg3(module_idP, CC_id, frameP, slotP);
|
||||
ra->state = WAIT_Msg3;
|
||||
@@ -990,7 +1025,7 @@ void nr_fill_rar(uint8_t Mod_idP,
|
||||
uint8_t * dlsch_buffer,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu){
|
||||
|
||||
LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index);
|
||||
LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u\n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index);
|
||||
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
|
||||
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
|
||||
unsigned char csi_req = 0, tpc_command;
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "NR_MAC_COMMON/nr_mac.h"
|
||||
#include "NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
|
||||
/*NFAPI*/
|
||||
@@ -455,7 +454,8 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n");
|
||||
|
||||
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
// for now HARQ PID is fixed and should be the same as in post-processor
|
||||
const int current_harq_pid = slot % num_slots_per_tdd;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
@@ -589,7 +589,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
1 /* nrOfLayers */)
|
||||
>> 3;
|
||||
|
||||
const int current_harq_pid = sched_ctrl->current_harq_pid;
|
||||
const int current_harq_pid = slot % num_slots_per_tdd;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx][sched_ctrl->pucch_occ_idx];
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
@@ -642,7 +642,15 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
retInfo->numDmrsCdmGrpsNoData);
|
||||
/* we do not have to do anything, since we do not require to get data
|
||||
* from RLC, encode MAC CEs, or copy data to FAPI structures */
|
||||
LOG_W(MAC, "%d.%2d retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
|
||||
LOG_W(MAC,
|
||||
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id,
|
||||
rnti,
|
||||
current_harq_pid,
|
||||
harq->round,
|
||||
harq->ndi);
|
||||
} else { /* initial transmission */
|
||||
|
||||
LOG_D(MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
|
||||
|
||||
@@ -258,8 +258,6 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd)
|
||||
{
|
||||
if (slot != 1)
|
||||
return; /* only schedule in slot 1 for now */
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
@@ -317,7 +315,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][RC.nrmac[module_id]->current_slot];
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
@@ -352,457 +350,131 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
vrb_map[rb + sched_ctrl->rbStart] = 1;
|
||||
}
|
||||
|
||||
void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
int *dci_formats, int *rnti_types,
|
||||
int time_domain_assignment, uint8_t tpc,
|
||||
int n_ubwp, int bwp_id) {
|
||||
void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
uint64_t ulsch_in_slot_bitmap) {
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
switch(dci_formats[(pdcch_pdu_rel15->numDlDci)-1]) {
|
||||
case NR_UL_DCI_FORMAT_0_0:
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size,
|
||||
pusch_pdu->rb_start,
|
||||
NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275));
|
||||
AssertFatal(UE_info->num_UEs <= 1,
|
||||
"%s() cannot handle more than one UE, but found %d\n",
|
||||
__func__,
|
||||
UE_info->num_UEs);
|
||||
if (UE_info->num_UEs == 0)
|
||||
return;
|
||||
|
||||
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
|
||||
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
|
||||
dci_pdu_rel15->mcs = 9;
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
|
||||
dci_pdu_rel15->format_indicator = 0;
|
||||
dci_pdu_rel15->ndi = 1;
|
||||
dci_pdu_rel15->rv = 0;
|
||||
dci_pdu_rel15->harq_pid = 0;
|
||||
dci_pdu_rel15->tpc = 1;
|
||||
break;
|
||||
case NR_UL_DCI_FORMAT_0_1:
|
||||
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
|
||||
dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
|
||||
dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
|
||||
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
|
||||
dci_pdu_rel15->dai[0].val = 0; //TODO
|
||||
// bwp indicator
|
||||
if (n_ubwp < 4)
|
||||
dci_pdu_rel15->bwp_indicator.val = bwp_id;
|
||||
else
|
||||
dci_pdu_rel15->bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
|
||||
// frequency domain assignment
|
||||
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1)
|
||||
dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size,
|
||||
pusch_pdu->rb_start,
|
||||
NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275));
|
||||
else
|
||||
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
|
||||
// time domain assignment
|
||||
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
|
||||
// mcs
|
||||
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
|
||||
// tpc command for pusch
|
||||
dci_pdu_rel15->tpc = tpc;
|
||||
// SRS resource indicator
|
||||
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
|
||||
if (*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook)
|
||||
dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS
|
||||
else
|
||||
AssertFatal(1==0,"Non Codebook configuration non supported\n");
|
||||
}
|
||||
// Antenna Ports
|
||||
dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank
|
||||
// DMRS sequence initialization
|
||||
dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
|
||||
break;
|
||||
default :
|
||||
AssertFatal(1==0,"Valid UL formats are 0_0 and 0_1 \n");
|
||||
}
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
|
||||
pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci],
|
||||
dci_pdu_rel15->frequency_domain_assignment.val,
|
||||
dci_pdu_rel15->time_domain_assignment.val,
|
||||
dci_pdu_rel15->frequency_hopping_flag.val,
|
||||
dci_pdu_rel15->mcs,
|
||||
dci_pdu_rel15->tpc,
|
||||
dci_pdu_rel15->ndi,
|
||||
dci_pdu_rel15->rv);
|
||||
|
||||
}
|
||||
|
||||
int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
|
||||
uint8_t hrq_id;
|
||||
uint8_t max_ul_harq_pids = 3; // temp: for testing
|
||||
// schedule active harq processes
|
||||
NR_UE_ul_harq_t cur_harq;
|
||||
for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
|
||||
cur_harq = sched_ctrl->ul_harq_processes[hrq_id];
|
||||
if (cur_harq.state==ACTIVE_NOT_SCHED) {
|
||||
#ifdef UL_HARQ_PRINT
|
||||
printf("[SCHED] Found ulharq id %d, scheduling it for retransmission\n",hrq_id);
|
||||
#endif
|
||||
return hrq_id;
|
||||
}
|
||||
}
|
||||
|
||||
// schedule new harq processes
|
||||
for (hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
|
||||
cur_harq = sched_ctrl->ul_harq_processes[hrq_id];
|
||||
if (cur_harq.state==INACTIVE) {
|
||||
#ifdef UL_HARQ_PRINT
|
||||
printf("[SCHED] Found new ulharq id %d, scheduling it\n",hrq_id);
|
||||
#endif
|
||||
return hrq_id;
|
||||
}
|
||||
}
|
||||
LOG_E(MAC,"All UL HARQ processes are busy. Cannot schedule ULSCH\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
|
||||
DevAssert(ubwp);
|
||||
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
if (tda_list->k2)
|
||||
return *tda_list->k2;
|
||||
else if (mu < 2)
|
||||
return 1;
|
||||
else if (mu == 2)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
|
||||
void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
int time_domain_assignment,
|
||||
uint64_t ulsch_in_slot_bitmap) {
|
||||
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
|
||||
int bwp_id=1;
|
||||
int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
int UE_id = 0;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
|
||||
NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
NR_PUSCH_Config_t *pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
|
||||
AssertFatal(time_domain_assignment<ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count,
|
||||
"time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count);
|
||||
|
||||
int K2 = get_K2(ubwp, time_domain_assignment,mu);
|
||||
/* check if slot is UL, and for phy test verify that it is in first TDD
|
||||
* period, slot 8 (for K2=2, this is at slot 6 in the gNB; because of UE
|
||||
const int tda = 1;
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
AssertFatal(tda < tdaList->list.count,
|
||||
"time domain assignment %d >= %d\n",
|
||||
tda,
|
||||
tdaList->list.count);
|
||||
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= num_slots_per_tdd);
|
||||
const int sched_slot = (slot + K2) % num_slots_per_tdd;
|
||||
/* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
|
||||
* limitations). Note that if K2 or the TDD configuration is changed, below
|
||||
* conditions might exclude each other and never be true */
|
||||
const int slot_idx = (slotP + K2) % num_slots_per_tdd;
|
||||
if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx)
|
||||
&& (!get_softmodem_params()->phy_test || slot_idx == 8)) {
|
||||
if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
|
||||
return;
|
||||
|
||||
nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0];
|
||||
UL_dci_req->SFN = frameP;
|
||||
UL_dci_req->Slot = slotP;
|
||||
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu;
|
||||
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
|
||||
int first_ul_slot = num_slots_per_tdd - ul_slots;
|
||||
NR_sched_pusch *pusch_sched = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot];
|
||||
pusch_sched->frame = frameP;
|
||||
pusch_sched->slot = slotP + K2;
|
||||
pusch_sched->active = true;
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &pusch_sched->pusch_pdu;
|
||||
memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t));
|
||||
|
||||
LOG_D(MAC, "Scheduling UE specific PUSCH\n");
|
||||
//UL_tti_req = &nr_mac->UL_tti_req[CC_id];
|
||||
|
||||
int dci_formats[2];
|
||||
int rnti_types[2];
|
||||
|
||||
NR_SearchSpace_t *ss;
|
||||
int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n");
|
||||
AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0,
|
||||
"searchPsacesToAddModList is empty\n");
|
||||
|
||||
int found=0;
|
||||
|
||||
for (int i=0;i<bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) {
|
||||
ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i];
|
||||
AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n");
|
||||
AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n");
|
||||
if (ss->searchSpaceType->present == target_ss) {
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(found==1,"Couldn't find an adequate searchspace\n");
|
||||
|
||||
if (ss->searchSpaceType->choice.ue_Specific->dci_Formats)
|
||||
dci_formats[0] = NR_UL_DCI_FORMAT_0_1;
|
||||
else
|
||||
dci_formats[0] = NR_UL_DCI_FORMAT_0_0;
|
||||
|
||||
rnti_types[0] = NR_RNTI_C;
|
||||
|
||||
//Resource Allocation in time domain
|
||||
int startSymbolAndLength=0;
|
||||
int StartSymbolIndex,NrOfSymbols,mapping_type;
|
||||
|
||||
startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength,&StartSymbolIndex,&NrOfSymbols);
|
||||
pusch_pdu->start_symbol_index = StartSymbolIndex;
|
||||
pusch_pdu->nr_of_symbols = NrOfSymbols;
|
||||
|
||||
mapping_type = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->mappingType;
|
||||
|
||||
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
|
||||
pusch_pdu->rnti = rnti;
|
||||
pusch_pdu->handle = 0; //not yet used
|
||||
|
||||
pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
pusch_pdu->cyclic_prefix = 0;
|
||||
|
||||
if (pusch_Config->transformPrecoder == NULL) {
|
||||
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL)
|
||||
pusch_pdu->transform_precoding = 1;
|
||||
else
|
||||
pusch_pdu->transform_precoding = 0;
|
||||
}
|
||||
else
|
||||
pusch_pdu->transform_precoding = *pusch_Config->transformPrecoder;
|
||||
if (pusch_Config->dataScramblingIdentityPUSCH != NULL)
|
||||
pusch_pdu->data_scrambling_id = *pusch_Config->dataScramblingIdentityPUSCH;
|
||||
else
|
||||
pusch_pdu->data_scrambling_id = *scc->physCellId;
|
||||
|
||||
pusch_pdu->mcs_index = 9;
|
||||
if (pusch_pdu->transform_precoding)
|
||||
pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0,
|
||||
dci_formats[0], rnti_types[0], target_ss, false);
|
||||
else
|
||||
pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1,
|
||||
dci_formats[0], rnti_types[0], target_ss, false);
|
||||
|
||||
pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
|
||||
pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table);
|
||||
if (pusch_Config->tp_pi2BPSK!=NULL) {
|
||||
if(((pusch_pdu->mcs_table==3)&&(pusch_pdu->mcs_index<2)) ||
|
||||
((pusch_pdu->mcs_table==4)&&(pusch_pdu->mcs_index<6))) {
|
||||
pusch_pdu->target_code_rate = pusch_pdu->target_code_rate>>1;
|
||||
pusch_pdu->qam_mod_order = pusch_pdu->qam_mod_order<<1;
|
||||
}
|
||||
}
|
||||
pusch_pdu->nrOfLayers = 1;
|
||||
|
||||
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
|
||||
if (pusch_Config->resourceAllocation==NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) {
|
||||
pusch_pdu->resource_alloc = 1; //type 1
|
||||
pusch_pdu->rb_start = 0;
|
||||
if (get_softmodem_params()->phy_test==1)
|
||||
pusch_pdu->rb_size = min(pusch_pdu->bwp_size,50);
|
||||
else
|
||||
pusch_pdu->rb_size = pusch_pdu->bwp_size;
|
||||
}
|
||||
else
|
||||
AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n");
|
||||
|
||||
pusch_pdu->vrb_to_prb_mapping = 0;
|
||||
|
||||
if (pusch_Config->frequencyHopping==NULL)
|
||||
pusch_pdu->frequency_hopping = 0;
|
||||
else
|
||||
pusch_pdu->frequency_hopping = 1;
|
||||
|
||||
//pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
|
||||
//pusch_pdu->uplink_frequency_shift_7p5khz = 0;
|
||||
|
||||
|
||||
// --------------------
|
||||
// ------- DMRS -------
|
||||
// --------------------
|
||||
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
|
||||
if (mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA)
|
||||
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup;
|
||||
else
|
||||
NR_DMRS_UplinkConfig = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
|
||||
if (NR_DMRS_UplinkConfig->dmrs_Type == NULL)
|
||||
pusch_pdu->dmrs_config_type = 0;
|
||||
else
|
||||
pusch_pdu->dmrs_config_type = 1;
|
||||
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
|
||||
if (pusch_pdu->transform_precoding) { // transform precoding disabled
|
||||
long *scramblingid;
|
||||
if (pusch_pdu->scid == 0)
|
||||
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
|
||||
else
|
||||
scramblingid = NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
|
||||
if (scramblingid == NULL)
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
else
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scramblingid;
|
||||
}
|
||||
else {
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
if (NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
|
||||
pusch_pdu->pusch_identity = *NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
|
||||
else
|
||||
pusch_pdu->pusch_identity = *scc->physCellId;
|
||||
}
|
||||
pusch_dmrs_AdditionalPosition_t additional_pos;
|
||||
if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL)
|
||||
additional_pos = 2;
|
||||
else {
|
||||
if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3)
|
||||
additional_pos = 3;
|
||||
else
|
||||
additional_pos = *NR_DMRS_UplinkConfig->dmrs_AdditionalPosition;
|
||||
}
|
||||
pusch_maxLength_t pusch_maxLength;
|
||||
if (NR_DMRS_UplinkConfig->maxLength == NULL)
|
||||
pusch_maxLength = 1;
|
||||
else
|
||||
pusch_maxLength = 2;
|
||||
uint16_t l_prime_mask = get_l_prime(pusch_pdu->nr_of_symbols, mapping_type, additional_pos, pusch_maxLength);
|
||||
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << pusch_pdu->start_symbol_index;
|
||||
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = 1;
|
||||
pusch_pdu->dmrs_ports = 1;
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// --------------------
|
||||
// ------- PTRS -------
|
||||
// --------------------
|
||||
if (NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
|
||||
// TODO to be fixed from RRC config
|
||||
uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig
|
||||
pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
|
||||
pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
|
||||
pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
|
||||
}
|
||||
else{
|
||||
pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
|
||||
//Optional Data only included if indicated in pduBitmap
|
||||
int8_t harq_id = select_ul_harq_pid(&UE_info->UE_sched_ctrl[UE_id]);
|
||||
if (harq_id < 0) return;
|
||||
NR_UE_ul_harq_t *cur_harq = &UE_info->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id];
|
||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
||||
|
||||
cur_harq->state = ACTIVE_SCHED;
|
||||
cur_harq->last_tx_slot = pusch_sched->slot;
|
||||
|
||||
uint8_t num_dmrs_symb = 0;
|
||||
|
||||
for(int dmrs_counter = pusch_pdu->start_symbol_index; dmrs_counter < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; dmrs_counter++)
|
||||
num_dmrs_symb += ((pusch_pdu->ul_dmrs_symb_pos >> dmrs_counter) & 1);
|
||||
|
||||
uint8_t N_PRB_DMRS;
|
||||
if (pusch_pdu->dmrs_config_type == 0) {
|
||||
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*6;
|
||||
}
|
||||
else {
|
||||
N_PRB_DMRS = pusch_pdu->num_dmrs_cdm_grps_no_data*4;
|
||||
}
|
||||
|
||||
pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order,
|
||||
pusch_pdu->target_code_rate,
|
||||
pusch_pdu->rb_size,
|
||||
pusch_pdu->nr_of_symbols,
|
||||
N_PRB_DMRS * num_dmrs_symb,
|
||||
0, //nb_rb_oh
|
||||
0,
|
||||
pusch_pdu->nrOfLayers)>>3;
|
||||
|
||||
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size;
|
||||
|
||||
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
|
||||
//pusch_pdu->pusch_data.cb_present_and_position;
|
||||
//pusch_pdu->pusch_uci;
|
||||
//pusch_pdu->pusch_ptrs;
|
||||
//pusch_pdu->dfts_ofdm;
|
||||
//beamforming
|
||||
//pusch_pdu->beamforming; //not used for now
|
||||
|
||||
|
||||
ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus];
|
||||
memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t));
|
||||
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
UL_dci_req->numPdus+=1;
|
||||
|
||||
|
||||
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP);
|
||||
|
||||
uint8_t nr_of_candidates, aggregation_level;
|
||||
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */);
|
||||
const int cid = coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][nr_mac->current_slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
int CCEIndex = allocate_nr_CCEs(nr_mac,
|
||||
bwp,
|
||||
coreset,
|
||||
aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (CCEIndex < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
pusch_sched->active = false;
|
||||
const uint16_t rbStart = 0;
|
||||
const uint16_t rbSize = 50; /* due to OAI UE limitations */
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * 275];
|
||||
for (int i = rbStart; i < rbStart + rbSize; ++i) {
|
||||
if (vrb_map_UL[i]) {
|
||||
LOG_E(MAC,
|
||||
"%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
|
||||
__func__,
|
||||
frame,
|
||||
slot,
|
||||
i);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
nr_configure_pdcch(nr_mac,
|
||||
pdcch_pdu_rel15,
|
||||
UE_info->rnti[UE_id],
|
||||
ss,
|
||||
coreset,
|
||||
scc,
|
||||
bwp,
|
||||
aggregation_level,
|
||||
CCEIndex);
|
||||
|
||||
dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t));
|
||||
config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_info->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id);
|
||||
fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id);
|
||||
free(dci_pdu_rel15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
return;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
sched_ctrl->sched_pusch.time_domain_allocation = tda;
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
* every TTI if we can save it, so check whether dci_format, TDA, or
|
||||
* num_dmrs_cdm_grps_no_data has changed and only then recompute */
|
||||
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
nr_save_pusch_fields(scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
ps);
|
||||
|
||||
const int mcs = 9;
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
sched_pusch->mcs = mcs;
|
||||
sched_pusch->rbStart = rbStart;
|
||||
sched_pusch->rbSize = rbSize;
|
||||
|
||||
/* Calculate TBS from MCS */
|
||||
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
|
||||
sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
|
||||
if (ps->pusch_Config->tp_pi2BPSK
|
||||
&& ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
|
||||
sched_pusch->R >>= 1;
|
||||
sched_pusch->Qm <<= 1;
|
||||
}
|
||||
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
||||
sched_pusch->R,
|
||||
sched_pusch->rbSize,
|
||||
ps->nrOfSymbols,
|
||||
ps->N_PRB_DMRS * ps->num_dmrs_symb,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
|
||||
vrb_map_UL[rb] = 1;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "assertions.h"
|
||||
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
|
||||
@@ -48,9 +47,6 @@
|
||||
#include "RRC/NR/nr_rrc_extern.h"
|
||||
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
||||
|
||||
//#include "LAYER2/MAC/pre_processor.c"
|
||||
#include "pdcp.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "T.h"
|
||||
@@ -213,6 +209,75 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
|
||||
}
|
||||
|
||||
void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_BWP_Uplink_t *ubwp,
|
||||
long dci_format,
|
||||
int tda,
|
||||
uint8_t num_dmrs_cdm_grps_no_data,
|
||||
NR_sched_pusch_save_t *ps)
|
||||
{
|
||||
ps->dci_format = dci_format;
|
||||
ps->time_domain_allocation = tda;
|
||||
ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength,
|
||||
&ps->startSymbolIndex,
|
||||
&ps->nrOfSymbols);
|
||||
|
||||
ps->pusch_Config = ubwp->bwp_Dedicated->pusch_Config->choice.setup;
|
||||
if (!ps->pusch_Config->transformPrecoder)
|
||||
ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder;
|
||||
else
|
||||
ps->transform_precoding = *ps->pusch_Config->transformPrecoder;
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
if (ps->transform_precoding)
|
||||
ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_Table,
|
||||
0,
|
||||
ps->dci_format,
|
||||
NR_RNTI_C,
|
||||
target_ss,
|
||||
false);
|
||||
else
|
||||
ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config->mcs_TableTransformPrecoder,
|
||||
1,
|
||||
ps->dci_format,
|
||||
NR_RNTI_C,
|
||||
target_ss,
|
||||
false);
|
||||
|
||||
/* DMRS calculations */
|
||||
ps->mapping_type = tdaList->list.array[tda]->mappingType;
|
||||
ps->NR_DMRS_UplinkConfig =
|
||||
ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA
|
||||
? ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup
|
||||
: ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup;
|
||||
ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1;
|
||||
const pusch_dmrs_AdditionalPosition_t additional_pos =
|
||||
ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL
|
||||
? 2
|
||||
: (*ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition ==
|
||||
NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3
|
||||
? 3
|
||||
: *ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition);
|
||||
const pusch_maxLength_t pusch_maxLength =
|
||||
ps->NR_DMRS_UplinkConfig->maxLength == NULL ? 1 : 2;
|
||||
const uint16_t l_prime_mask = get_l_prime(ps->nrOfSymbols,
|
||||
ps->mapping_type,
|
||||
additional_pos,
|
||||
pusch_maxLength);
|
||||
ps->ul_dmrs_symb_pos = l_prime_mask << ps->startSymbolIndex;
|
||||
uint8_t num_dmrs_symb = 0;
|
||||
for(int i = ps->startSymbolIndex; i < ps->startSymbolIndex + ps->nrOfSymbols; i++)
|
||||
num_dmrs_symb += (ps->ul_dmrs_symb_pos >> i) & 1;
|
||||
ps->num_dmrs_symb = num_dmrs_symb;
|
||||
ps->N_PRB_DMRS = ps->dmrs_config_type == 0
|
||||
? num_dmrs_cdm_grps_no_data * 6
|
||||
: num_dmrs_cdm_grps_no_data * 4;
|
||||
}
|
||||
|
||||
void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
|
||||
nr_scs_e scs_common,
|
||||
nr_scs_e pdcch_scs,
|
||||
@@ -637,6 +702,81 @@ void nr_fill_nfapi_dl_pdu(int Mod_idP,
|
||||
dl_req->nPDUs += 2;
|
||||
}
|
||||
|
||||
void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
int *dci_formats,
|
||||
int time_domain_assignment, uint8_t tpc,
|
||||
int n_ubwp, int bwp_id) {
|
||||
const int bw = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275);
|
||||
switch (dci_formats[(pdcch_pdu_rel15->numDlDci) - 1]) {
|
||||
case NR_UL_DCI_FORMAT_0_0:
|
||||
dci_pdu_rel15->frequency_domain_assignment.val =
|
||||
PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
|
||||
|
||||
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
|
||||
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
|
||||
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
|
||||
|
||||
dci_pdu_rel15->format_indicator = 0;
|
||||
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
|
||||
dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
|
||||
dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
|
||||
dci_pdu_rel15->tpc = tpc;
|
||||
break;
|
||||
case NR_UL_DCI_FORMAT_0_1:
|
||||
dci_pdu_rel15->ndi = pusch_pdu->pusch_data.new_data_indicator;
|
||||
dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index;
|
||||
dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id;
|
||||
dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping;
|
||||
dci_pdu_rel15->dai[0].val = 0; //TODO
|
||||
// bwp indicator
|
||||
if (n_ubwp < 4)
|
||||
dci_pdu_rel15->bwp_indicator.val = bwp_id;
|
||||
else
|
||||
dci_pdu_rel15->bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212
|
||||
// frequency domain assignment
|
||||
AssertFatal(ubwp->bwp_Dedicated->pusch_Config->choice.setup->resourceAllocation
|
||||
== NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
|
||||
"Only frequency resource allocation type 1 is currently supported\n");
|
||||
dci_pdu_rel15->frequency_domain_assignment.val =
|
||||
PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw);
|
||||
// time domain assignment
|
||||
dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment;
|
||||
// mcs
|
||||
dci_pdu_rel15->mcs = pusch_pdu->mcs_index;
|
||||
// tpc command for pusch
|
||||
dci_pdu_rel15->tpc = tpc;
|
||||
// SRS resource indicator
|
||||
if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig != NULL) {
|
||||
AssertFatal(*ubwp->bwp_Dedicated->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook,
|
||||
"Non Codebook configuration non supported\n");
|
||||
dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS
|
||||
}
|
||||
// Antenna Ports
|
||||
dci_pdu_rel15->antenna_ports.val = 0; // TODO for now it is hardcoded, it should depends on cdm group no data and rank
|
||||
// DMRS sequence initialization
|
||||
dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
|
||||
break;
|
||||
default :
|
||||
AssertFatal(0, "Valid UL formats are 0_0 and 0_1\n");
|
||||
}
|
||||
|
||||
LOG_D(MAC,
|
||||
"%s() ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, "
|
||||
"time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n",
|
||||
__func__,
|
||||
pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci],
|
||||
dci_pdu_rel15->frequency_domain_assignment.val,
|
||||
dci_pdu_rel15->time_domain_assignment.val,
|
||||
dci_pdu_rel15->frequency_hopping_flag.val,
|
||||
dci_pdu_rel15->mcs,
|
||||
dci_pdu_rel15->tpc,
|
||||
dci_pdu_rel15->ndi,
|
||||
dci_pdu_rel15->rv);
|
||||
}
|
||||
|
||||
void nr_configure_pdcch(gNB_MAC_INST *nr_mac,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
|
||||
uint16_t rnti,
|
||||
@@ -1721,20 +1861,17 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_update = 31;
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_apply = false;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0;
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
UE_info->UE_sched_ctrl[UE_id].pusch_save.time_domain_allocation = -1;
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch **)malloc(num_slots_ul*sizeof(NR_sched_pucch *));
|
||||
for (int s=0; s<num_slots_ul;s++)
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pucch[s] = (NR_sched_pucch *)malloc(2*sizeof(NR_sched_pucch));
|
||||
UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch));
|
||||
|
||||
for (int k=0; k<num_slots_ul; k++) {
|
||||
for (int l=0; l<2; l++)
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k],
|
||||
0,
|
||||
sizeof(NR_sched_pusch));
|
||||
}
|
||||
LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
|
||||
mod_idP,
|
||||
@@ -1776,7 +1913,6 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
|
||||
UE_info->rnti[UE_id] = 0;
|
||||
remove_nr_ue_list(&UE_info->list, UE_id);
|
||||
free(UE_info->UE_sched_ctrl[UE_id].sched_pucch);
|
||||
free(UE_info->UE_sched_ctrl[UE_id].sched_pusch);
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id],
|
||||
0,
|
||||
sizeof(NR_UE_sched_ctrl_t));
|
||||
|
||||
@@ -39,51 +39,59 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
int nr_ulmix_slots,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP) {
|
||||
|
||||
uint16_t O_csi, O_ack, O_uci;
|
||||
uint8_t O_sr = 0; // no SR in PUCCH implemented for now
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id);
|
||||
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
int bwp_id=1;
|
||||
NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1];
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0];
|
||||
|
||||
NR_sched_pucch *curr_pucch;
|
||||
|
||||
for (int k=0; k<nr_ulmix_slots; k++) {
|
||||
for (int l=0; l<2; l++) {
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
|
||||
O_ack = curr_pucch->dai_c;
|
||||
O_csi = curr_pucch->csi_bits;
|
||||
O_uci = O_ack + O_csi + O_sr;
|
||||
if ((O_uci>0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) {
|
||||
UL_tti_req->SFN = curr_pucch->frame;
|
||||
UL_tti_req->Slot = curr_pucch->ul_slot;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
|
||||
UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].pucch_pdu;
|
||||
memset(pucch_pdu,0,sizeof(nfapi_nr_pucch_pdu_t));
|
||||
UL_tti_req->n_pdus+=1;
|
||||
NR_sched_pucch *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l];
|
||||
const uint16_t O_ack = curr_pucch->dai_c;
|
||||
const uint16_t O_csi = curr_pucch->csi_bits;
|
||||
const uint8_t O_sr = 0; // no SR in PUCCH implemented for now
|
||||
if (O_ack + O_csi + O_sr == 0
|
||||
|| frameP != curr_pucch->frame
|
||||
|| slotP != curr_pucch->ul_slot)
|
||||
continue;
|
||||
|
||||
LOG_D(MAC,"Scheduling pucch reception for frame %d slot %d with (%d, %d, %d) (SR ACK, CSI) bits\n",
|
||||
frameP,slotP,O_sr,O_ack,curr_pucch->csi_bits);
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
|
||||
&RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][curr_pucch->ul_slot];
|
||||
AssertFatal(future_ul_tti_req->SFN == curr_pucch->frame
|
||||
&& future_ul_tti_req->Slot == curr_pucch->ul_slot,
|
||||
"future UL_tti_req's frame.slot %d.%d does not match PUCCH %d.%d\n",
|
||||
future_ul_tti_req->SFN,
|
||||
future_ul_tti_req->Slot,
|
||||
curr_pucch->frame,
|
||||
curr_pucch->ul_slot);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pucch_pdu_t);
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pucch_pdu;
|
||||
memset(pucch_pdu, 0, sizeof(nfapi_nr_pucch_pdu_t));
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
|
||||
nr_configure_pucch(pucch_pdu,
|
||||
scc,
|
||||
ubwp,
|
||||
UE_info->rnti[UE_id],
|
||||
curr_pucch->resource_indicator,
|
||||
O_csi,
|
||||
O_ack,
|
||||
O_sr);
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d Scheduling pucch reception in %4d.%2d: bits SR %d, ACK %d, CSI %d, k %d l %d\n",
|
||||
frameP,
|
||||
slotP,
|
||||
curr_pucch->frame,
|
||||
curr_pucch->ul_slot,
|
||||
O_sr,
|
||||
O_ack,
|
||||
O_csi,
|
||||
k, l);
|
||||
|
||||
memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
}
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
nr_configure_pucch(pucch_pdu,
|
||||
scc,
|
||||
UE_info->UE_sched_ctrl[UE_id].active_ubwp,
|
||||
UE_info->rnti[UE_id],
|
||||
curr_pucch->resource_indicator,
|
||||
O_csi,
|
||||
O_ack,
|
||||
O_sr);
|
||||
|
||||
memset(&UE_info->UE_sched_ctrl[UE_id].sched_pucch[k][l],
|
||||
0,
|
||||
sizeof(NR_sched_pucch));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +155,7 @@ void compute_csi_bitlen (NR_CellGroupConfig_t *secondaryCellGroup, NR_UE_info_t
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen =0;
|
||||
}
|
||||
|
||||
LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d",
|
||||
LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n",
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].cri_ssbri_bitlen,
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].rsrp_bitlen,
|
||||
UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen[0].diff_rsrp_bitlen);
|
||||
@@ -213,7 +221,7 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
if ( (frame%(period/n_slots_frame)==(offset/n_slots_frame)) && (slot==((sched_slot/slots_per_tdd)*slots_per_tdd))) {
|
||||
|
||||
// we are scheduling pucch for csi in the first pucch occasion (this comes before ack/nack)
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[sched_slot-slots_per_tdd+ul_slots][0];
|
||||
curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[(sched_slot%slots_per_tdd)-slots_per_tdd+ul_slots][0];
|
||||
|
||||
NR_PUCCH_CSI_Resource_t *pucchcsires = csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list.array[0];
|
||||
|
||||
@@ -266,15 +274,27 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
}
|
||||
|
||||
|
||||
void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234,
|
||||
NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
|
||||
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01)
|
||||
{
|
||||
int UE_id = find_nr_UE_id(mod_id, uci_01->rnti);
|
||||
if (UE_id < 0) {
|
||||
LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_01->rnti);
|
||||
return;
|
||||
}
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
|
||||
uci_01->ul_cqi,
|
||||
30);
|
||||
|
||||
// TODO
|
||||
int max_harq_rounds = 4; // TODO define macro
|
||||
|
||||
if (uci_01 != NULL) {
|
||||
if (((uci_01->pduBitmap >> 1) & 0x01)) {
|
||||
// handle harq
|
||||
int harq_idx_s = 0;
|
||||
|
||||
@@ -283,7 +303,7 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
// search for the right harq process
|
||||
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) {
|
||||
// if the gNB received ack with a good confidence
|
||||
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
if ((slot - 1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
|
||||
if ((uci_01->harq->harq_list[harq_bit].harq_value == 1) &&
|
||||
(uci_01->harq->harq_confidence_level == 0)) {
|
||||
@@ -299,13 +319,13 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
stats->dlsch_errors++;
|
||||
UE_info->mac_stats[UE_id].dlsch_errors++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if feedback slot processing is aborted
|
||||
else if (sched_ctrl->harq_processes[harq_idx].feedback_slot != -1
|
||||
&& (UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
|
||||
&& (slot - 1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
|
||||
&& sched_ctrl->harq_processes[harq_idx].is_waiting) {
|
||||
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
@@ -318,9 +338,29 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234)
|
||||
{
|
||||
int UE_id = find_nr_UE_id(mod_id, uci_234->rnti);
|
||||
if (UE_id < 0) {
|
||||
LOG_E(MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti);
|
||||
return;
|
||||
}
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
if (uci_234 != NULL) {
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
|
||||
uci_234->ul_cqi,
|
||||
30);
|
||||
|
||||
// TODO
|
||||
int max_harq_rounds = 4; // TODO define macro
|
||||
if ((uci_234->pduBitmap >> 1) & 0x01) {
|
||||
int harq_idx_s = 0;
|
||||
int acknack;
|
||||
|
||||
@@ -329,7 +369,7 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
acknack = ((uci_234->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01;
|
||||
for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) {
|
||||
// if the gNB received ack with a good confidence or if the max harq rounds was reached
|
||||
if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
if ((slot - 1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) {
|
||||
// TODO add some confidence level for when there is no CRC
|
||||
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
|
||||
if ((uci_234->harq.harq_crc != 1) && acknack) {
|
||||
@@ -345,13 +385,13 @@ void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) {
|
||||
sched_ctrl->harq_processes[harq_idx].ndi ^= 1;
|
||||
sched_ctrl->harq_processes[harq_idx].round = 0;
|
||||
stats->dlsch_errors++;
|
||||
UE_info->mac_stats[UE_id].dlsch_errors++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// if feedback slot processing is aborted
|
||||
else if (sched_ctrl->harq_processes[harq_idx].feedback_slot != -1
|
||||
&& (UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
|
||||
&& (slot - 1) > sched_ctrl->harq_processes[harq_idx].feedback_slot
|
||||
&& sched_ctrl->harq_processes[harq_idx].is_waiting) {
|
||||
sched_ctrl->harq_processes[harq_idx].feedback_slot = -1;
|
||||
sched_ctrl->harq_processes[harq_idx].round++;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
|
||||
void nr_process_mac_pdu(
|
||||
@@ -246,37 +246,58 @@ void nr_process_mac_pdu(
|
||||
}
|
||||
}
|
||||
|
||||
void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu) {
|
||||
void handle_nr_ul_harq(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_crc_t *crc_pdu)
|
||||
{
|
||||
int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti);
|
||||
if (UE_id < 0) {
|
||||
LOG_E(MAC, "%s(): unknown RNTI %04x in PUSCH\n", __func__, crc_pdu->rnti);
|
||||
return;
|
||||
}
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
int max_harq_rounds = 4; // TODO define macro
|
||||
uint8_t hrq_id = crc_pdu.harq_id;
|
||||
uint8_t hrq_id = crc_pdu->harq_id;
|
||||
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
|
||||
if (cur_harq->state==ACTIVE_SCHED) {
|
||||
if (!crc_pdu.tb_crc_status) {
|
||||
if (!crc_pdu->tb_crc_status) {
|
||||
cur_harq->ndi ^= 1;
|
||||
cur_harq->round = 0;
|
||||
cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant
|
||||
#ifdef UL_HARQ_PRINT
|
||||
printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id);
|
||||
#endif
|
||||
LOG_D(MAC,
|
||||
"Ulharq id %d crc passed for RNTI %04x\n",
|
||||
hrq_id,
|
||||
crc_pdu->rnti);
|
||||
} else {
|
||||
cur_harq->round++;
|
||||
cur_harq->state = ACTIVE_NOT_SCHED;
|
||||
#ifdef UL_HARQ_PRINT
|
||||
printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id);
|
||||
#endif
|
||||
LOG_D(MAC,
|
||||
"Ulharq id %d crc failed for RNTI %04x\n",
|
||||
hrq_id,
|
||||
crc_pdu->rnti);
|
||||
}
|
||||
|
||||
if (!(cur_harq->round<max_harq_rounds)) {
|
||||
cur_harq->ndi ^= 1;
|
||||
cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive
|
||||
cur_harq->round = 0;
|
||||
LOG_D(MAC,"[HARQ HANDLER] RNTI %x: Ulharq id %d crc failed in all round, freeing it for scheduler\n",crc_pdu.rnti,hrq_id);
|
||||
stats->ulsch_errors++;
|
||||
LOG_D(MAC,
|
||||
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
|
||||
crc_pdu->rnti,
|
||||
hrq_id);
|
||||
UE_info->mac_stats[UE_id].ulsch_errors++;
|
||||
}
|
||||
return;
|
||||
} else
|
||||
LOG_W(MAC,"Incorrect ULSCH HARQ process %d or invalid state %d (ignore this warning for RA)\n",hrq_id,cur_harq->state);
|
||||
LOG_W(MAC,
|
||||
"Incorrect ULSCH HARQ PID %d or invalid state %d for RNTI %04x "
|
||||
"(ignore this warning for RA)\n",
|
||||
hrq_id,
|
||||
cur_harq->state,
|
||||
crc_pdu->rnti);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -384,6 +405,11 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
bwpList->list.count);
|
||||
const int bwp_id = 1;
|
||||
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
|
||||
struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList;
|
||||
AssertFatal(ubwpList->list.count == 1,
|
||||
"uplinkBWP_ToAddModList has %d BWP!\n",
|
||||
ubwpList->list.count);
|
||||
UE_info->UE_sched_ctrl[UE_id].active_ubwp = ubwpList->list.array[bwp_id - 1];
|
||||
LOG_I(MAC,
|
||||
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
|
||||
"adding UE MAC Context UE_id %d/RNTI %04x\n",
|
||||
@@ -400,8 +426,389 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
"reset RA state information for RA-RNTI %04x/index %d\n",
|
||||
ra->rnti,
|
||||
i);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
|
||||
DevAssert(ubwp);
|
||||
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
|
||||
if (tda_list->k2)
|
||||
return *tda_list->k2;
|
||||
else if (mu < 2)
|
||||
return 1;
|
||||
else if (mu == 2)
|
||||
return 2;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
|
||||
int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
const uint8_t max_ul_harq_pids = 3; // temp: for testing
|
||||
// schedule active harq processes
|
||||
for (uint8_t hrq_id = 0; hrq_id < max_ul_harq_pids; hrq_id++) {
|
||||
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
|
||||
if (cur_harq->state == ACTIVE_NOT_SCHED) {
|
||||
LOG_D(MAC, "Found ulharq id %d, scheduling it for retransmission\n", hrq_id);
|
||||
return hrq_id;
|
||||
}
|
||||
}
|
||||
|
||||
// schedule new harq processes
|
||||
for (uint8_t hrq_id=0; hrq_id < max_ul_harq_pids; hrq_id++) {
|
||||
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id];
|
||||
if (cur_harq->state == INACTIVE) {
|
||||
LOG_D(MAC, "Found new ulharq id %d, scheduling it\n", hrq_id);
|
||||
return hrq_id;
|
||||
}
|
||||
}
|
||||
LOG_E(MAC, "All UL HARQ processes are busy. Cannot schedule ULSCH\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
uint64_t ulsch_in_slot_bitmap) {
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
NR_COMMON_channels_t *cc = nr_mac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
AssertFatal(UE_info->num_UEs <= 1,
|
||||
"%s() cannot handle more than one UE, but found %d\n",
|
||||
__func__,
|
||||
UE_info->num_UEs);
|
||||
if (UE_info->num_UEs == 0)
|
||||
return;
|
||||
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
const int tda = 1;
|
||||
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
|
||||
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
|
||||
AssertFatal(tda < tdaList->list.count,
|
||||
"time domain assignment %d >= %d\n",
|
||||
tda,
|
||||
tdaList->list.count);
|
||||
int K2 = get_K2(sched_ctrl->active_ubwp, tda, mu);
|
||||
const int sched_frame = frame + (slot + K2 >= num_slots_per_tdd);
|
||||
const int sched_slot = (slot + K2) % num_slots_per_tdd;
|
||||
if (!is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot))
|
||||
return;
|
||||
|
||||
/* get first, largest unallocated region */
|
||||
uint16_t *vrb_map_UL =
|
||||
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * 275];
|
||||
uint16_t rbStart = 0;
|
||||
while (vrb_map_UL[rbStart]) rbStart++;
|
||||
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
uint16_t rbSize = 1;
|
||||
while (rbStart + rbSize < bwpSize && !vrb_map_UL[rbStart+rbSize])
|
||||
rbSize++;
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
|
||||
const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
|
||||
sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
|
||||
uint8_t nr_of_candidates;
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space);
|
||||
sched_ctrl->coreset = get_coreset(
|
||||
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
|
||||
const int m = UE_info->num_pdcch_cand[UE_id][cid];
|
||||
sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id],
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->coreset,
|
||||
sched_ctrl->aggregation_level,
|
||||
Y,
|
||||
m,
|
||||
nr_of_candidates);
|
||||
if (sched_ctrl->cce_index < 0) {
|
||||
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
|
||||
return;
|
||||
}
|
||||
UE_info->num_pdcch_cand[UE_id][cid]++;
|
||||
|
||||
sched_ctrl->sched_pusch.time_domain_allocation = tda;
|
||||
const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
|
||||
const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = 1;
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
* every TTI if we can save it, so check whether dci_format, TDA, or
|
||||
* num_dmrs_cdm_grps_no_data has changed and only then recompute */
|
||||
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
nr_save_pusch_fields(scc,
|
||||
sched_ctrl->active_ubwp,
|
||||
dci_format,
|
||||
tda,
|
||||
num_dmrs_cdm_grps_no_data,
|
||||
ps);
|
||||
|
||||
const int mcs = 9;
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
sched_pusch->mcs = mcs;
|
||||
sched_pusch->rbStart = rbStart;
|
||||
sched_pusch->rbSize = rbSize;
|
||||
|
||||
/* Calculate TBS from MCS */
|
||||
sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
|
||||
sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
|
||||
if (ps->pusch_Config->tp_pi2BPSK
|
||||
&& ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
|
||||
sched_pusch->R >>= 1;
|
||||
sched_pusch->Qm <<= 1;
|
||||
}
|
||||
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
|
||||
sched_pusch->R,
|
||||
sched_pusch->rbSize,
|
||||
ps->nrOfSymbols,
|
||||
ps->N_PRB_DMRS * ps->num_dmrs_symb,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
vrb_map_UL[rb + sched_ctrl->sched_pusch.rbStart] = 1;
|
||||
}
|
||||
|
||||
void nr_schedule_ulsch(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
uint64_t ulsch_in_slot_bitmap) {
|
||||
RC.nrmac[module_id]->pre_processor_ul(
|
||||
module_id, frame, slot, num_slots_per_tdd, ulsch_in_slot_bitmap);
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const NR_UE_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
|
||||
* every TTI are pre-populated by the preprocessor and used below */
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
if (sched_pusch->rbSize <= 0)
|
||||
continue;
|
||||
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
|
||||
int8_t harq_id = select_ul_harq_pid(sched_ctrl);
|
||||
if (harq_id < 0) return;
|
||||
NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[harq_id];
|
||||
cur_harq->state = ACTIVE_SCHED;
|
||||
cur_harq->last_tx_slot = sched_pusch->slot;
|
||||
|
||||
int rnti_types[2] = { NR_RNTI_C, 0 };
|
||||
|
||||
/* pre-computed PUSCH values that only change if time domain allocation,
|
||||
* DCI format, or DMRS parameters change. Updated in the preprocessor
|
||||
* through nr_save_pusch_fields() */
|
||||
NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
|
||||
|
||||
/* Statistics */
|
||||
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) {
|
||||
UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
} else {
|
||||
LOG_W(MAC,
|
||||
"%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n",
|
||||
frame,
|
||||
slot,
|
||||
rnti,
|
||||
sched_pusch->frame,
|
||||
sched_pusch->slot,
|
||||
harq_id,
|
||||
cur_harq->round,
|
||||
cur_harq->ndi);
|
||||
}
|
||||
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
|
||||
frame,
|
||||
slot,
|
||||
rnti,
|
||||
sched_pusch->frame,
|
||||
sched_pusch->slot,
|
||||
sched_pusch->rbStart,
|
||||
sched_pusch->rbSize,
|
||||
sched_pusch->mcs,
|
||||
sched_pusch->tb_size,
|
||||
harq_id,
|
||||
cur_harq->round,
|
||||
cur_harq->ndi);
|
||||
|
||||
/* PUSCH in a later slot, but corresponding DCI now! */
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][sched_pusch->slot];
|
||||
AssertFatal(future_ul_tti_req->SFN == sched_pusch->frame
|
||||
&& future_ul_tti_req->Slot == sched_pusch->slot,
|
||||
"%d.%d future UL_tti_req's frame.slot %d.%d does not match PUSCH %d.%d\n",
|
||||
frame, slot,
|
||||
future_ul_tti_req->SFN,
|
||||
future_ul_tti_req->Slot,
|
||||
sched_pusch->frame,
|
||||
sched_pusch->slot);
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
|
||||
future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu;
|
||||
memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
|
||||
LOG_D(MAC, "%4d.%2d Scheduling UE specific PUSCH\n", frame, slot);
|
||||
|
||||
pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
|
||||
pusch_pdu->rnti = rnti;
|
||||
pusch_pdu->handle = 0; //not yet used
|
||||
|
||||
/* FAPI: BWP */
|
||||
pusch_pdu->bwp_size = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pusch_pdu->bwp_start = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
pusch_pdu->subcarrier_spacing = sched_ctrl->active_ubwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
pusch_pdu->cyclic_prefix = 0;
|
||||
|
||||
/* FAPI: PUSCH information always included */
|
||||
pusch_pdu->target_code_rate = sched_pusch->R;
|
||||
pusch_pdu->qam_mod_order = sched_pusch->Qm;
|
||||
pusch_pdu->mcs_index = sched_pusch->mcs;
|
||||
pusch_pdu->mcs_table = ps->mcs_table;
|
||||
pusch_pdu->transform_precoding = ps->transform_precoding;
|
||||
if (ps->pusch_Config->dataScramblingIdentityPUSCH)
|
||||
pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH;
|
||||
else
|
||||
pusch_pdu->data_scrambling_id = *scc->physCellId;
|
||||
pusch_pdu->nrOfLayers = 1;
|
||||
|
||||
/* FAPI: DMRS */
|
||||
pusch_pdu->ul_dmrs_symb_pos = ps->ul_dmrs_symb_pos;
|
||||
pusch_pdu->dmrs_config_type = ps->dmrs_config_type;
|
||||
if (pusch_pdu->transform_precoding) { // transform precoding disabled
|
||||
long *scramblingid;
|
||||
if (pusch_pdu->scid == 0)
|
||||
scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID0;
|
||||
else
|
||||
scramblingid = ps->NR_DMRS_UplinkConfig->transformPrecodingDisabled->scramblingID1;
|
||||
if (scramblingid == NULL)
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
else
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scramblingid;
|
||||
}
|
||||
else {
|
||||
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
|
||||
if (ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity != NULL)
|
||||
pusch_pdu->pusch_identity = *ps->NR_DMRS_UplinkConfig->transformPrecodingEnabled->nPUSCH_Identity;
|
||||
else
|
||||
pusch_pdu->pusch_identity = *scc->physCellId;
|
||||
}
|
||||
pusch_pdu->scid = 0; // DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]
|
||||
pusch_pdu->num_dmrs_cdm_grps_no_data = ps->num_dmrs_cdm_grps_no_data;
|
||||
pusch_pdu->dmrs_ports = 1;
|
||||
|
||||
/* FAPI: Pusch Allocation in frequency domain */
|
||||
AssertFatal(ps->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1,
|
||||
"Only frequency resource allocation type 1 is currently supported\n");
|
||||
pusch_pdu->resource_alloc = 1; //type 1
|
||||
pusch_pdu->rb_start = sched_pusch->rbStart;
|
||||
pusch_pdu->rb_size = sched_pusch->rbSize;
|
||||
pusch_pdu->vrb_to_prb_mapping = 0;
|
||||
if (ps->pusch_Config->frequencyHopping==NULL)
|
||||
pusch_pdu->frequency_hopping = 0;
|
||||
else
|
||||
pusch_pdu->frequency_hopping = 1;
|
||||
|
||||
/* FAPI: Resource Allocation in time domain */
|
||||
pusch_pdu->start_symbol_index = ps->startSymbolIndex;
|
||||
pusch_pdu->nr_of_symbols = ps->nrOfSymbols;
|
||||
|
||||
/* PUSCH PDU */
|
||||
pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round];
|
||||
pusch_pdu->pusch_data.harq_process_id = harq_id;
|
||||
pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi;
|
||||
pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size;
|
||||
pusch_pdu->pusch_data.num_cb = 0; //CBG not supported
|
||||
|
||||
/* PUSCH PTRS */
|
||||
if (ps->NR_DMRS_UplinkConfig->phaseTrackingRS != NULL) {
|
||||
// TODO to be fixed from RRC config
|
||||
uint8_t ptrs_mcs1 = 2; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint8_t ptrs_mcs2 = 4; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint8_t ptrs_mcs3 = 10; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint16_t n_rb0 = 25; // higher layer parameter in PTRS-UplinkConfig
|
||||
uint16_t n_rb1 = 75; // higher layer parameter in PTRS-UplinkConfig
|
||||
pusch_pdu->pusch_ptrs.ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, pusch_pdu->mcs_index, pusch_pdu->mcs_table);
|
||||
pusch_pdu->pusch_ptrs.ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, pusch_pdu->rb_size);
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t));
|
||||
pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
|
||||
|
||||
pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS
|
||||
}
|
||||
else{
|
||||
pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
|
||||
}
|
||||
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_req = &RC.nrmac[module_id]->UL_dci_req[0];
|
||||
ul_dci_req->SFN = frame;
|
||||
ul_dci_req->Slot = slot;
|
||||
nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu = &ul_dci_req->ul_dci_pdu_list[ul_dci_req->numPdus];
|
||||
memset(ul_dci_request_pdu, 0, sizeof(nfapi_nr_ul_dci_request_pdus_t));
|
||||
ul_dci_request_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
|
||||
ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
ul_dci_req->numPdus += 1;
|
||||
|
||||
LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frame,slot);
|
||||
|
||||
nr_configure_pdcch(RC.nrmac[0],
|
||||
pdcch_pdu_rel15,
|
||||
rnti,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
sched_ctrl->active_bwp,
|
||||
sched_ctrl->aggregation_level,
|
||||
sched_ctrl->cce_index);
|
||||
|
||||
dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET];
|
||||
memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15));
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id];
|
||||
const int n_ubwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count;
|
||||
// NOTE: below functions assume that dci_formats is an array corresponding
|
||||
// to all UL DCIs in the PDCCH, but for us it is a simple int. So before
|
||||
// having multiple UEs, the below need to be changed (IMO the functions
|
||||
// should fill for one DCI only and not handle all of them).
|
||||
config_uldci(sched_ctrl->active_ubwp,
|
||||
pusch_pdu,
|
||||
pdcch_pdu_rel15,
|
||||
&dci_pdu_rel15[0],
|
||||
&ps->dci_format,
|
||||
ps->time_domain_allocation,
|
||||
UE_info->UE_sched_ctrl[UE_id].tpc0,
|
||||
n_ubwp,
|
||||
sched_ctrl->active_bwp->bwp_Id);
|
||||
fill_dci_pdu_rel15(scc,
|
||||
secondaryCellGroup,
|
||||
pdcch_pdu_rel15,
|
||||
dci_pdu_rel15,
|
||||
&ps->dci_format,
|
||||
rnti_types,
|
||||
pusch_pdu->bwp_size,
|
||||
sched_ctrl->active_bwp->bwp_Id);
|
||||
|
||||
memset(sched_pusch, 0, sizeof(*sched_pusch));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,20 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, uint8_t slots_per_frame);
|
||||
|
||||
/// uplink scheduler
|
||||
void nr_schedule_ulsch(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
void nr_simple_ulsch_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
/////// Random Access MAC-PHY interface functions and primitives ///////
|
||||
|
||||
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
|
||||
@@ -107,7 +121,9 @@ void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
|
||||
|
||||
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
|
||||
|
||||
void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc,
|
||||
void nr_get_Msg3alloc(module_id_t module_id,
|
||||
int CC_id,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_BWP_Uplink_t *ubwp,
|
||||
sub_frame_t current_subframe,
|
||||
frame_t current_frame,
|
||||
@@ -136,6 +152,13 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
|
||||
* fixed set of resources */
|
||||
void nr_ul_preprocessor_phytest(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
@@ -157,26 +180,24 @@ void nr_fill_nfapi_dl_pdu(int Mod_id,
|
||||
int ndi,
|
||||
int round);
|
||||
|
||||
void nr_rx_acknack(nfapi_nr_uci_pusch_pdu_t *uci_pusch,
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01,
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234,
|
||||
NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats);
|
||||
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_01);
|
||||
void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_234);
|
||||
|
||||
|
||||
void config_uldci(NR_BWP_Uplink_t *ubwp,
|
||||
nfapi_nr_pusch_pdu_t *pusch_pdu,
|
||||
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15,
|
||||
dci_pdu_rel15_t *dci_pdu_rel15,
|
||||
int *dci_formats, int *rnti_types,
|
||||
int *dci_formats,
|
||||
int time_domain_assignment, uint8_t tpc,
|
||||
int n_ubwp, int bwp_id);
|
||||
|
||||
void nr_schedule_pusch(int Mod_idP,
|
||||
int UE_id,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
void nr_schedule_pucch(int Mod_idP,
|
||||
int UE_id,
|
||||
int nr_ulmix_slots,
|
||||
@@ -279,6 +300,15 @@ void find_aggregation_candidates(uint8_t *aggregation_level,
|
||||
uint8_t *nr_of_candidates,
|
||||
NR_SearchSpace_t *ss);
|
||||
|
||||
long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
|
||||
|
||||
void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_BWP_Uplink_t *ubwp,
|
||||
long dci_format,
|
||||
int tda,
|
||||
uint8_t num_dmrs_cdm_grps_no_data,
|
||||
NR_sched_pusch_save_t *ps);
|
||||
|
||||
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
|
||||
|
||||
int get_spf(nfapi_nr_config_request_scf_t *cfg);
|
||||
@@ -353,16 +383,6 @@ void nr_generate_Msg2(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP);
|
||||
|
||||
void schedule_fapi_ul_pdu(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int num_slots_per_tdd,
|
||||
int ul_slots,
|
||||
int time_domain_assignment,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
void nr_process_mac_pdu(
|
||||
module_id_t module_idP,
|
||||
rnti_t rnti,
|
||||
@@ -398,7 +418,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
const uint8_t ul_cqi,
|
||||
const uint16_t rssi);
|
||||
|
||||
void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu);
|
||||
void handle_nr_ul_harq(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_crc_t *crc_pdu);
|
||||
|
||||
int16_t ssb_index_from_prach(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
@@ -409,5 +432,4 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
|
||||
|
||||
void find_SSB_and_RO_available(module_id_t module_idP);
|
||||
|
||||
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10);
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "assertions.h"
|
||||
|
||||
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
|
||||
#include "RRC/NR/nr_rrc_defs.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
@@ -82,10 +81,13 @@ void mac_top_init_gNB(void)
|
||||
|
||||
RC.nrmac[i]->ul_handle = 0;
|
||||
|
||||
if (get_softmodem_params()->phy_test)
|
||||
if (get_softmodem_params()->phy_test) {
|
||||
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
|
||||
else
|
||||
RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
|
||||
} else {
|
||||
RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor;
|
||||
RC.nrmac[i]->pre_processor_ul = nr_simple_ulsch_preprocessor;
|
||||
}
|
||||
|
||||
}//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@
|
||||
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
|
||||
/* MAC */
|
||||
#include "LAYER2/MAC/mac.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
|
||||
#include "NR_TAG.h"
|
||||
@@ -142,8 +140,6 @@ typedef struct {
|
||||
uint8_t msg3_cqireq;
|
||||
/// Round of Msg3 HARQ
|
||||
uint8_t msg3_round;
|
||||
/// Msg3 pusch pdu
|
||||
nfapi_nr_pusch_pdu_t pusch_pdu;
|
||||
/// TBS used for Msg4
|
||||
int msg4_TBsize;
|
||||
/// MCS used for Msg4
|
||||
@@ -192,8 +188,9 @@ typedef struct {
|
||||
NR_RA_t ra[NR_NB_RA_PROC_MAX];
|
||||
/// VRB map for common channels
|
||||
uint16_t vrb_map[275];
|
||||
/// VRB map for common channels and retransmissions by PHICH
|
||||
uint16_t vrb_map_UL[275];
|
||||
/// VRB map for common channels and PUSCH, dynamically allocated because
|
||||
/// length depends on number of slots and RBs
|
||||
uint16_t *vrb_map_UL;
|
||||
/// number of subframe allocation pattern available for MBSFN sync area
|
||||
uint8_t num_sf_allocation_pattern;
|
||||
///Number of active SSBs
|
||||
@@ -285,12 +282,49 @@ typedef struct NR_sched_pucch {
|
||||
uint8_t resource_indicator;
|
||||
} NR_sched_pucch;
|
||||
|
||||
/* this struct is a helper: as long as the TDA and DCI format remain the same
|
||||
* over the same uBWP and search space, there is no need to recalculate all
|
||||
* S/L, MCS table, or DMRS-related parameters over and over again. Hence, we
|
||||
* store them in this struct for easy reference. */
|
||||
typedef struct NR_sched_pusch_save {
|
||||
int dci_format;
|
||||
int time_domain_allocation;
|
||||
uint8_t num_dmrs_cdm_grps_no_data;
|
||||
|
||||
int startSymbolIndex;
|
||||
int nrOfSymbols;
|
||||
|
||||
NR_PUSCH_Config_t *pusch_Config;
|
||||
uint8_t transform_precoding;
|
||||
uint8_t mcs_table;
|
||||
|
||||
long mapping_type;
|
||||
NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig;
|
||||
uint16_t dmrs_config_type;
|
||||
uint16_t ul_dmrs_symb_pos;
|
||||
uint8_t num_dmrs_symb;
|
||||
uint8_t N_PRB_DMRS;
|
||||
} NR_sched_pusch_save_t;
|
||||
|
||||
typedef struct NR_sched_pusch {
|
||||
int frame;
|
||||
int slot;
|
||||
bool active;
|
||||
nfapi_nr_pusch_pdu_t pusch_pdu;
|
||||
} NR_sched_pusch;
|
||||
|
||||
/// RB allocation within active uBWP
|
||||
uint16_t rbSize;
|
||||
uint16_t rbStart;
|
||||
|
||||
// time-domain allocation for scheduled RBs
|
||||
int time_domain_allocation;
|
||||
|
||||
/// MCS
|
||||
uint8_t mcs;
|
||||
|
||||
/// TBS-related info
|
||||
uint16_t R;
|
||||
uint8_t Qm;
|
||||
uint32_t tb_size;
|
||||
} NR_sched_pusch_t;
|
||||
|
||||
typedef struct NR_UE_harq {
|
||||
uint8_t is_waiting;
|
||||
@@ -348,11 +382,15 @@ typedef struct {
|
||||
|
||||
/// the currently active BWP in DL
|
||||
NR_BWP_Downlink_t *active_bwp;
|
||||
/// the currently active BWP in UL
|
||||
NR_BWP_Uplink_t *active_ubwp;
|
||||
|
||||
NR_sched_pucch **sched_pucch;
|
||||
/// selected PUCCH index, if scheduled
|
||||
int pucch_sched_idx;
|
||||
int pucch_occ_idx;
|
||||
NR_sched_pusch *sched_pusch;
|
||||
NR_sched_pusch_save_t pusch_save;
|
||||
NR_sched_pusch_t sched_pusch;
|
||||
|
||||
/// CCE index and aggregation, should be coherent with cce_list
|
||||
NR_SearchSpace_t *search_space;
|
||||
@@ -381,7 +419,6 @@ typedef struct {
|
||||
uint8_t tpc0;
|
||||
uint8_t tpc1;
|
||||
uint16_t ul_rssi;
|
||||
uint8_t current_harq_pid;
|
||||
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||
NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||
int dummy;
|
||||
@@ -418,7 +455,6 @@ typedef struct {
|
||||
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
|
||||
#define MAX_CSI_REPORTCONFIG 48
|
||||
typedef struct {
|
||||
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
|
||||
/// scheduling control info
|
||||
nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG];
|
||||
NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
|
||||
@@ -441,6 +477,11 @@ typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd);
|
||||
typedef void (*nr_pp_impl_ul)(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int num_slots_per_tdd,
|
||||
uint64_t ulsch_in_slot_bitmap);
|
||||
|
||||
/*! \brief top level eNB MAC structure */
|
||||
typedef struct gNB_MAC_INST_s {
|
||||
@@ -467,8 +508,12 @@ typedef struct gNB_MAC_INST_s {
|
||||
nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX];
|
||||
/// NFAPI DL Config Request Structure
|
||||
nfapi_nr_dl_tti_request_t DL_req[NFAPI_CC_MAX];
|
||||
/// NFAPI UL TTI Request Structure (this is from the new SCF specs)
|
||||
nfapi_nr_ul_tti_request_t UL_tti_req[NFAPI_CC_MAX];
|
||||
/// NFAPI UL TTI Request Structure, simple pointer into structure
|
||||
/// UL_tti_req_ahead for current frame/slot
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req[NFAPI_CC_MAX];
|
||||
/// NFAPI UL TTI Request Structure for future TTIs, dynamically allocated
|
||||
/// because length depends on number of slots
|
||||
nfapi_nr_ul_tti_request_t *UL_tti_req_ahead[NFAPI_CC_MAX];
|
||||
/// NFAPI HI/DCI0 Config Request Structure
|
||||
nfapi_nr_ul_dci_request_t UL_dci_req[NFAPI_CC_MAX];
|
||||
/// NFAPI DL PDU structure
|
||||
@@ -502,11 +547,11 @@ typedef struct gNB_MAC_INST_s {
|
||||
time_stats_t schedule_pch;
|
||||
/// CCE lists
|
||||
int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE];
|
||||
/// current slot
|
||||
int current_slot;
|
||||
|
||||
/// DL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_dl pre_processor_dl;
|
||||
/// UL preprocessor for differentiated scheduling
|
||||
nr_pp_impl_ul pre_processor_ul;
|
||||
} gNB_MAC_INST;
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_GNB_H__ */
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "pdcp.h"
|
||||
|
||||
int decode_t_reordering(int v)
|
||||
{
|
||||
static int tab[36] = {
|
||||
0, 1, 2, 4, 5, 8, 10, 15, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, 180,
|
||||
200, 220, 240, 260, 280, 300, 500, 750, 1000, 1250, 1500, 1750, 2000,
|
||||
2250, 2500, 2750, 3000
|
||||
};
|
||||
|
||||
if (v < 0 || v > 35) {
|
||||
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return tab[v];
|
||||
}
|
||||
|
||||
int decode_sn_size_ul(long s)
|
||||
{
|
||||
if (s == 0) return 12;
|
||||
if (s == 1) return 18;
|
||||
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int decode_sn_size_dl(long s)
|
||||
{
|
||||
if (s == 0) return 12;
|
||||
if (s == 1) return 18;
|
||||
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int decode_discard_timer(long v)
|
||||
{
|
||||
static int tab[16] = {
|
||||
10, 20, 30, 40, 50, 60, 75, 100, 150, 200, 250, 300, 500, 750, 1500, -1,
|
||||
};
|
||||
|
||||
if (v < 0 || v > 15) {
|
||||
LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return tab[v];
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_
|
||||
#define _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_
|
||||
|
||||
int decode_t_reordering(int v);
|
||||
int decode_sn_size_ul(long s);
|
||||
int decode_sn_size_dl(long s);
|
||||
int decode_discard_timer(long v);
|
||||
|
||||
#endif /* _OPENAIR2_LAYER2_NR_PDCP_ASN1_UTILS_H_ */
|
||||
@@ -44,7 +44,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
|
||||
void *deliver_sdu_data,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
||||
char *buf, int size, int sdu_id),
|
||||
void *deliver_pdu_data)
|
||||
void *deliver_pdu_data,
|
||||
int sn_size,
|
||||
int t_reordering,
|
||||
int discard_timer)
|
||||
{
|
||||
nr_pdcp_entity_drb_am_t *ret;
|
||||
|
||||
@@ -66,9 +69,12 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
|
||||
ret->common.deliver_pdu = deliver_pdu;
|
||||
ret->common.deliver_pdu_data = deliver_pdu_data;
|
||||
|
||||
ret->rb_id = rb_id;
|
||||
ret->rb_id = rb_id;
|
||||
ret->sn_size = sn_size;
|
||||
ret->t_reordering = t_reordering;
|
||||
ret->discard_timer = discard_timer;
|
||||
|
||||
ret->common.maximum_nr_pdcp_sn = 4095;
|
||||
ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
|
||||
|
||||
return (nr_pdcp_entity_t *)ret;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,10 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
|
||||
void *deliver_sdu_data,
|
||||
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
|
||||
char *buf, int size, int sdu_id),
|
||||
void *deliver_pdu_data);
|
||||
void *deliver_pdu_data,
|
||||
int sn_size,
|
||||
int t_reordering,
|
||||
int discard_timer);
|
||||
|
||||
void nr_DRB_preconfiguration(uint16_t crnti);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int
|
||||
{
|
||||
nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
|
||||
int sn;
|
||||
char buf[size+2];
|
||||
char buf[size+3];
|
||||
|
||||
sn = entity->common.next_nr_pdcp_tx_sn;
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
typedef struct {
|
||||
nr_pdcp_entity_t common;
|
||||
int rb_id;
|
||||
int sn_size; /* unit: bits */
|
||||
int t_reordering; /* unit: ms */
|
||||
int discard_timer; /* unit: ms, -1 means infinity */
|
||||
} nr_pdcp_entity_drb_am_t;
|
||||
|
||||
void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include "asn1_utils.h"
|
||||
#include "nr_pdcp_ue_manager.h"
|
||||
#include "NR_RadioBearerConfig.h"
|
||||
#include "NR_RLC-BearerConfig.h"
|
||||
@@ -596,8 +597,17 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
|
||||
nr_pdcp_ue_t *ue;
|
||||
|
||||
int drb_id = s->drb_Identity;
|
||||
int t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering);
|
||||
int sn_size_ul = decode_sn_size_ul(*s->pdcp_Config->drb->pdcp_SN_SizeUL);
|
||||
int sn_size_dl = decode_sn_size_dl(*s->pdcp_Config->drb->pdcp_SN_SizeDL);
|
||||
int discard_timer = decode_discard_timer(*s->pdcp_Config->drb->discardTimer);
|
||||
|
||||
LOG_I(PDCP, "%s: adding drb %d for rnti %x\n", __FUNCTION__, drb_id, rnti);
|
||||
/* TODO(?): accept different UL and DL SN sizes? */
|
||||
if (sn_size_ul != sn_size_dl) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal, bad SN sizes, must be same. ul=%d, dl=%d\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, sn_size_ul, sn_size_dl);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (drb_id != 1) {
|
||||
LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n",
|
||||
@@ -611,7 +621,8 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
|
||||
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
|
||||
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
} else {
|
||||
pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue);
|
||||
pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue,
|
||||
sn_size_dl, t_reordering, discard_timer);
|
||||
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
|
||||
|
||||
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
|
||||
|
||||
@@ -991,3 +991,13 @@ void nr_rlc_tick(int frame, int subframe)
|
||||
nr_rlc_current_time++;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a hack, to compile the gNB.
|
||||
* TODO: remove it. The solution is to cleanup cmake_targets/CMakeLists.txt
|
||||
*/
|
||||
void rlc_tick(int a, int b)
|
||||
{
|
||||
LOG_E(RLC, "%s:%d:%s: this code should not be reached\n",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -177,14 +177,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
|
||||
mac_rlc_status_resp_t ret;
|
||||
rlc_entity_t *rb;
|
||||
|
||||
/* TODO: handle time a bit more properly */
|
||||
if (rlc_current_time_last_frame != frameP ||
|
||||
rlc_current_time_last_subframe != subframeP) {
|
||||
rlc_current_time++;
|
||||
rlc_current_time_last_frame = frameP;
|
||||
rlc_current_time_last_subframe = subframeP;
|
||||
}
|
||||
|
||||
rlc_manager_lock(rlc_ue_manager);
|
||||
ue = rlc_manager_get_ue(rlc_ue_manager, rntiP);
|
||||
|
||||
@@ -244,14 +236,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* TODO: handle time a bit more properly */
|
||||
if (rlc_current_time_last_frame != frameP ||
|
||||
rlc_current_time_last_subframe != subframeP) {
|
||||
rlc_current_time++;
|
||||
rlc_current_time_last_frame = frameP;
|
||||
rlc_current_time_last_subframe = subframeP;
|
||||
}
|
||||
|
||||
rlc_manager_lock(rlc_ue_manager);
|
||||
ue = rlc_manager_get_ue(rlc_ue_manager, rntiP);
|
||||
|
||||
@@ -1024,3 +1008,27 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x)
|
||||
|
||||
return RLC_OP_STATUS_OK;
|
||||
}
|
||||
|
||||
void rlc_tick(int frame, int subframe)
|
||||
{
|
||||
int expected_next_frame;
|
||||
int expected_next_subframe;
|
||||
|
||||
if (frame != rlc_current_time_last_frame ||
|
||||
subframe != rlc_current_time_last_subframe) {
|
||||
/* warn if discontinuity in ticks */
|
||||
expected_next_subframe = (rlc_current_time_last_subframe + 1) % 10;
|
||||
if (expected_next_subframe == 0)
|
||||
expected_next_frame = (rlc_current_time_last_frame + 1) % 1024;
|
||||
else
|
||||
expected_next_frame = rlc_current_time_last_frame;
|
||||
if (expected_next_frame != frame || expected_next_subframe != subframe)
|
||||
LOG_W(RLC, "rlc_tick: discontinuity (expected %d.%d, got %d.%d)\n",
|
||||
expected_next_frame, expected_next_subframe,
|
||||
frame, subframe);
|
||||
|
||||
rlc_current_time++;
|
||||
rlc_current_time_last_frame = frame;
|
||||
rlc_current_time_last_subframe = subframe;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,12 +30,9 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "openair1/PHY/defs_eNB.h"
|
||||
#include "openair1/PHY/phy_extern.h"
|
||||
#include "openair1/SCHED_NR/fapi_nr_l1.h"
|
||||
#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h"
|
||||
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
|
||||
#include "LAYER2/MAC/mac_proto.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
@@ -79,35 +76,28 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
|
||||
}
|
||||
|
||||
|
||||
void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) {
|
||||
|
||||
void handle_nr_uci(NR_UL_IND_t *UL_info)
|
||||
{
|
||||
const module_id_t mod_id = UL_info->module_id;
|
||||
const frame_t frame = UL_info->frame;
|
||||
const sub_frame_t slot = UL_info->slot;
|
||||
int num_ucis = UL_info->uci_ind.num_ucis;
|
||||
nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list;
|
||||
|
||||
for (int i = 0; i < num_ucis; i++) {
|
||||
switch (uci_list[i].pdu_type) {
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE: break;
|
||||
case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
|
||||
LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
|
||||
nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
|
||||
|
||||
if( (uci_pdu->pduBitmap>>1) & 0x01)
|
||||
nr_rx_acknack(NULL,uci_pdu,NULL,UL_info,sched_ctrl,stats);
|
||||
|
||||
const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1;
|
||||
handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu);
|
||||
break;
|
||||
}
|
||||
case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
|
||||
nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
|
||||
|
||||
// tpc (power control)
|
||||
sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30);
|
||||
|
||||
if( (uci_pdu->pduBitmap>>1) & 0x01)
|
||||
nr_rx_acknack(NULL,NULL,uci_pdu,UL_info,sched_ctrl,stats);
|
||||
|
||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4;
|
||||
handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -117,75 +107,62 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_
|
||||
}
|
||||
|
||||
|
||||
void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) {
|
||||
void handle_nr_ulsch(NR_UL_IND_t *UL_info)
|
||||
{
|
||||
if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) {
|
||||
for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) {
|
||||
for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) {
|
||||
// find crc_indication j corresponding rx_indication i
|
||||
const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i];
|
||||
const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j];
|
||||
LOG_D(PHY,
|
||||
"UL_info->crc_ind.pdu_list[%d].rnti:%04x "
|
||||
"UL_info->rx_ind.pdu_list[%d].rnti:%04x\n",
|
||||
j,
|
||||
crc->rnti,
|
||||
i,
|
||||
rx->rnti);
|
||||
|
||||
if(nfapi_mode == 1) {
|
||||
if (UL_info->crc_ind.number_crcs>0) {
|
||||
//LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf));
|
||||
// oai_nfapi_crc_indication(&UL_info->crc_ind);
|
||||
if (crc->rnti != rx->rnti)
|
||||
continue;
|
||||
|
||||
UL_info->crc_ind.number_crcs = 0;
|
||||
}
|
||||
LOG_D(MAC,
|
||||
"%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n",
|
||||
UL_info->frame,
|
||||
UL_info->slot,
|
||||
crc->tb_crc_status ? "error" : "ok",
|
||||
crc->tb_crc_status);
|
||||
|
||||
if (UL_info->rx_ind.number_of_pdus>0) {
|
||||
//LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf));
|
||||
// oai_nfapi_rx_ind(&UL_info->rx_ind);
|
||||
UL_info->rx_ind.number_of_pdus = 0;
|
||||
}
|
||||
} else {
|
||||
/* if CRC passes, pass PDU, otherwise pass NULL as error indication */
|
||||
nr_rx_sdu(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot,
|
||||
rx->rnti,
|
||||
crc->tb_crc_status ? NULL : rx->pdu,
|
||||
rx->pdu_length,
|
||||
rx->timing_advance,
|
||||
rx->ul_cqi,
|
||||
rx->rssi);
|
||||
handle_nr_ul_harq(UL_info->module_id, UL_info->frame, UL_info->slot, crc);
|
||||
break;
|
||||
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
|
||||
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
|
||||
|
||||
if (UL_info->rx_ind.number_of_pdus>0 && UL_info->crc_ind.number_crcs>0) {
|
||||
for (int i=0; i<UL_info->rx_ind.number_of_pdus; i++) {
|
||||
for (int j=0; j<UL_info->crc_ind.number_crcs; j++) {
|
||||
// find crc_indication j corresponding rx_indication i
|
||||
LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j,
|
||||
UL_info->crc_ind.crc_list[j].rnti, i, UL_info->rx_ind.pdu_list[i].rnti);
|
||||
|
||||
if (UL_info->crc_ind.crc_list[j].rnti ==
|
||||
UL_info->rx_ind.pdu_list[i].rnti) {
|
||||
LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status);
|
||||
|
||||
handle_nr_ul_harq(UL_info->slot, sched_ctrl, stats, UL_info->crc_ind.crc_list[j]);
|
||||
|
||||
if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication
|
||||
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot);
|
||||
|
||||
nr_rx_sdu(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
UL_info->rx_ind.sfn, //UL_info->frame,
|
||||
UL_info->rx_ind.slot, //UL_info->slot,
|
||||
UL_info->rx_ind.pdu_list[i].rnti,
|
||||
(uint8_t *)NULL,
|
||||
UL_info->rx_ind.pdu_list[i].pdu_length,
|
||||
UL_info->rx_ind.pdu_list[i].timing_advance,
|
||||
UL_info->rx_ind.pdu_list[i].ul_cqi,
|
||||
UL_info->rx_ind.pdu_list[i].rssi);
|
||||
} else {
|
||||
LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot);
|
||||
nr_rx_sdu(UL_info->module_id,
|
||||
UL_info->CC_id,
|
||||
UL_info->rx_ind.sfn, //UL_info->frame,
|
||||
UL_info->rx_ind.slot, //UL_info->slot,
|
||||
UL_info->rx_ind.pdu_list[i].rnti,
|
||||
UL_info->rx_ind.pdu_list[i].pdu,
|
||||
UL_info->rx_ind.pdu_list[i].pdu_length,
|
||||
UL_info->rx_ind.pdu_list[i].timing_advance,
|
||||
UL_info->rx_ind.pdu_list[i].ul_cqi,
|
||||
UL_info->rx_ind.pdu_list[i].rssi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // for (j=0;j<UL_info->crc_ind.number_crcs;j++)
|
||||
} // for (i=0;i<UL_info->rx_ind.number_of_pdus;i++)
|
||||
|
||||
UL_info->crc_ind.number_crcs=0;
|
||||
UL_info->rx_ind.number_of_pdus = 0;
|
||||
}
|
||||
else if (UL_info->rx_ind.number_of_pdus!=0 || UL_info->crc_ind.number_crcs!=0) {
|
||||
LOG_E(PHY,"hoping not to have mis-match between CRC ind and RX ind - hopefully the missing message is coming shortly rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
|
||||
UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot,
|
||||
UL_info->crc_ind.number_crcs, UL_info->rx_ind.sfn, UL_info->rx_ind.slot);
|
||||
}
|
||||
UL_info->crc_ind.number_crcs = 0;
|
||||
UL_info->rx_ind.number_of_pdus = 0;
|
||||
} else if (UL_info->rx_ind.number_of_pdus != 0
|
||||
|| UL_info->crc_ind.number_crcs != 0) {
|
||||
LOG_E(PHY,
|
||||
"hoping not to have mis-match between CRC ind and RX ind - "
|
||||
"hopefully the missing message is coming shortly "
|
||||
"rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n",
|
||||
UL_info->rx_ind.number_of_pdus,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot,
|
||||
UL_info->crc_ind.number_crcs,
|
||||
UL_info->rx_ind.sfn,
|
||||
UL_info->rx_ind.slot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,14 +193,12 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
ifi->CC_mask |= (1<<CC_id);
|
||||
}
|
||||
|
||||
// clear DL/UL info for new scheduling round
|
||||
clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot);
|
||||
handle_nr_rach(UL_info);
|
||||
|
||||
handle_nr_uci(UL_info,&mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0],mac->pucch_target_snrx10);
|
||||
handle_nr_uci(UL_info);
|
||||
// clear HI prior to handling ULSCH
|
||||
mac->UL_dci_req[CC_id].numPdus = 0;
|
||||
handle_nr_ulsch(UL_info, &mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0]);
|
||||
handle_nr_ulsch(UL_info);
|
||||
|
||||
if (nfapi_mode != 1) {
|
||||
if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
|
||||
@@ -246,7 +221,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
sched_info->DL_req = &mac->DL_req[CC_id];
|
||||
sched_info->UL_dci_req = &mac->UL_dci_req[CC_id];
|
||||
|
||||
sched_info->UL_tti_req = &mac->UL_tti_req[CC_id];
|
||||
sched_info->UL_tti_req = mac->UL_tti_req[CC_id];
|
||||
|
||||
sched_info->TX_req = &mac->TX_req[CC_id];
|
||||
#ifdef DUMP_FAPI
|
||||
|
||||
@@ -58,9 +58,22 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
|
||||
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
|
||||
|
||||
if(servingcellconfigcommon->ssb_PositionsInBurst->present !=2)
|
||||
AssertFatal(1==0,"Currenrly implemented only for medium size SSB bitmap\n");
|
||||
uint8_t bitmap = servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0];
|
||||
uint64_t bitmap=0;
|
||||
switch (servingcellconfigcommon->ssb_PositionsInBurst->present) {
|
||||
case 1 :
|
||||
bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.shortBitmap.buf[0])<<56;
|
||||
break;
|
||||
case 2 :
|
||||
bitmap = ((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.mediumBitmap.buf[0])<<56;
|
||||
break;
|
||||
case 3 :
|
||||
for (int i=0; i<8; i++) {
|
||||
bitmap |= (((uint64_t) servingcellconfigcommon->ssb_PositionsInBurst->choice.longBitmap.buf[i])<<((7-i)*8));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(1==0,"SSB bitmap size value %d undefined (allowed values 1,2,3) \n", servingcellconfigcommon->ssb_PositionsInBurst->present);
|
||||
}
|
||||
|
||||
memset(secondaryCellGroup,0,sizeof(NR_CellGroupConfig_t));
|
||||
secondaryCellGroup->cellGroupId = scg_id;
|
||||
@@ -206,9 +219,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList));
|
||||
|
||||
int n_ssb = 0;
|
||||
NR_TCI_State_t *tcic[8];
|
||||
for (int i=0;i<8;i++) {
|
||||
if ((bitmap>>(7-i))&0x01){
|
||||
NR_TCI_State_t *tcic[64];
|
||||
for (int i=0;i<64;i++) {
|
||||
if ((bitmap>>(63-i))&0x01){
|
||||
tcic[i]=calloc(1,sizeof(*tcic[i]));
|
||||
tcic[i]->tci_StateId=n_ssb;
|
||||
tcic[i]->qcl_Type1.cell=NULL;
|
||||
@@ -367,12 +380,21 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL;
|
||||
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet));
|
||||
|
||||
int curr_bwp = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275);
|
||||
|
||||
NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset));
|
||||
coreset->controlResourceSetId=1;
|
||||
// frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B,
|
||||
// frequency domain resources depends on BWP size
|
||||
// options are 24, 48 or 96
|
||||
coreset->frequencyDomainResources.buf = calloc(1,6);
|
||||
coreset->frequencyDomainResources.buf[0] = 0xff;
|
||||
coreset->frequencyDomainResources.buf[1] = 0xff;
|
||||
if (curr_bwp < 48)
|
||||
coreset->frequencyDomainResources.buf[0] = 0xf0;
|
||||
else
|
||||
coreset->frequencyDomainResources.buf[0] = 0xff;
|
||||
if (curr_bwp < 96)
|
||||
coreset->frequencyDomainResources.buf[1] = 0;
|
||||
else
|
||||
coreset->frequencyDomainResources.buf[1] = 0xff;
|
||||
coreset->frequencyDomainResources.buf[2] = 0;
|
||||
coreset->frequencyDomainResources.buf[3] = 0;
|
||||
coreset->frequencyDomainResources.buf[4] = 0;
|
||||
@@ -384,9 +406,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
|
||||
|
||||
coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList));
|
||||
NR_TCI_StateId_t *tci[8];
|
||||
for (int i=0;i<8;i++) {
|
||||
if ((bitmap>>(7-i))&0x01){
|
||||
NR_TCI_StateId_t *tci[64];
|
||||
for (int i=0;i<64;i++) {
|
||||
if ((bitmap>>(63-i))&0x01){
|
||||
tci[i]=calloc(1,sizeof(*tci[i]));
|
||||
*tci[i] = i;
|
||||
ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]);
|
||||
@@ -486,7 +508,12 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ss2->nrofCandidates=calloc(1,sizeof(*ss2->nrofCandidates));
|
||||
ss2->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
|
||||
ss2->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
|
||||
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4;
|
||||
if (curr_bwp < 48)
|
||||
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
|
||||
else if (curr_bwp < 96)
|
||||
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
|
||||
else
|
||||
ss2->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n4;
|
||||
ss2->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
|
||||
ss2->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
|
||||
ss2->searchSpaceType=calloc(1,sizeof(*ss2->searchSpaceType));
|
||||
@@ -608,9 +635,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
|
||||
|
||||
n_ssb = 0;
|
||||
NR_TCI_State_t *tcid[8];
|
||||
for (int i=0;i<8;i++) {
|
||||
if ((bitmap>>(7-i))&0x01){
|
||||
NR_TCI_State_t *tcid[64];
|
||||
for (int i=0;i<64;i++) {
|
||||
if ((bitmap>>(63-i))&0x01){
|
||||
tcid[i]=calloc(1,sizeof(*tcid[i]));
|
||||
tcid[i]->tci_StateId=n_ssb;
|
||||
tcid[i]->qcl_Type1.cell=NULL;
|
||||
@@ -870,7 +897,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2));
|
||||
NR_PUCCH_Resource_t *pucchres3=calloc(1,sizeof(*pucchres3));
|
||||
pucchres0->pucch_ResourceId=1;
|
||||
pucchres0->startingPRB=48;
|
||||
pucchres0->startingPRB=8;
|
||||
pucchres0->intraSlotFrequencyHopping=NULL;
|
||||
pucchres0->secondHopPRB=NULL;
|
||||
pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
|
||||
@@ -881,7 +908,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
|
||||
|
||||
pucchres1->pucch_ResourceId=2;
|
||||
pucchres1->startingPRB=48;
|
||||
pucchres1->startingPRB=8;
|
||||
pucchres1->intraSlotFrequencyHopping=NULL;
|
||||
pucchres1->secondHopPRB=NULL;
|
||||
pucchres1->format.present= NR_PUCCH_Resource__format_PR_format0;
|
||||
@@ -892,23 +919,23 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres1);
|
||||
|
||||
pucchres2->pucch_ResourceId=3;
|
||||
pucchres2->startingPRB=40;
|
||||
pucchres2->startingPRB=0;
|
||||
pucchres2->intraSlotFrequencyHopping=NULL;
|
||||
pucchres2->secondHopPRB=NULL;
|
||||
pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2;
|
||||
pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2));
|
||||
pucchres2->format.choice.format2->nrofPRBs=4;
|
||||
pucchres2->format.choice.format2->nrofPRBs=8;
|
||||
pucchres2->format.choice.format2->nrofSymbols=1;
|
||||
pucchres2->format.choice.format2->startingSymbolIndex=13;
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2);
|
||||
|
||||
pucchres3->pucch_ResourceId=4;
|
||||
pucchres3->startingPRB=40;
|
||||
pucchres3->startingPRB=0;
|
||||
pucchres3->intraSlotFrequencyHopping=NULL;
|
||||
pucchres3->secondHopPRB=NULL;
|
||||
pucchres3->format.present= NR_PUCCH_Resource__format_PR_format2;
|
||||
pucchres3->format.choice.format2=calloc(1,sizeof(*pucchres3->format.choice.format2));
|
||||
pucchres3->format.choice.format2->nrofPRBs=4;
|
||||
pucchres3->format.choice.format2->nrofPRBs=8;
|
||||
pucchres3->format.choice.format2->nrofSymbols=1;
|
||||
pucchres3->format.choice.format2->startingSymbolIndex=12;
|
||||
ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres3);
|
||||
@@ -1031,45 +1058,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
|
||||
NR_CSI_SSB_ResourceSet_t *ssbresset0 = calloc(1,sizeof(*ssbresset0));
|
||||
ssbresset0->csi_SSB_ResourceSetId=0;
|
||||
if ((bitmap>>7)&0x01){
|
||||
NR_SSB_Index_t *ssbresset00=calloc(1,sizeof(*ssbresset00));
|
||||
*ssbresset00=0;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset00);
|
||||
}
|
||||
if ((bitmap>>6)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset01=calloc(1,sizeof(*ssbresset01));
|
||||
*ssbresset01=1;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset01);
|
||||
}
|
||||
if ((bitmap>>5)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset02=calloc(1,sizeof(*ssbresset02));
|
||||
*ssbresset02=2;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset02);
|
||||
}
|
||||
if ((bitmap>>4)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset03=calloc(1,sizeof(*ssbresset03));
|
||||
*ssbresset03=3;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset03);
|
||||
}
|
||||
if ((bitmap>>3)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset04=calloc(1,sizeof(*ssbresset04));
|
||||
*ssbresset04=4;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset04);
|
||||
}
|
||||
if ((bitmap>>2)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset05=calloc(1,sizeof(*ssbresset05));
|
||||
*ssbresset05=5;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset05);
|
||||
}
|
||||
if ((bitmap>>1)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset06=calloc(1,sizeof(*ssbresset06));
|
||||
*ssbresset06=6;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset06);
|
||||
}
|
||||
if ((bitmap)&0x01) {
|
||||
NR_SSB_Index_t *ssbresset07=calloc(1,sizeof(*ssbresset07));
|
||||
*ssbresset07=7;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset07);
|
||||
|
||||
NR_SSB_Index_t *ssbresset[64];
|
||||
for (int i=0;i<64;i++) {
|
||||
if ((bitmap>>(63-i))&0x01){
|
||||
ssbresset[i]=calloc(1,sizeof(*ssbresset[i]));
|
||||
*ssbresset[i] = i;
|
||||
ASN_SEQUENCE_ADD(&ssbresset0->csi_SSB_ResourceList.list,ssbresset[i]);
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list,ssbresset0);
|
||||
|
||||
|
||||
@@ -310,14 +310,21 @@ void x2ap_eNB_handle_register_eNB(instance_t instance,
|
||||
x2ap_register_eNB->t_dc_overall);
|
||||
|
||||
for (int i = 0; i< x2ap_register_eNB->num_cc; i++) {
|
||||
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
|
||||
new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i];
|
||||
if(new_instance->cell_type == CELL_MACRO_GNB){
|
||||
new_instance->nr_band[i] = x2ap_register_eNB->nr_band[i];
|
||||
new_instance->tdd_nRARFCN[i] = x2ap_register_eNB->nrARFCN[i];
|
||||
}
|
||||
else{
|
||||
new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i];
|
||||
new_instance->downlink_frequency[i] = x2ap_register_eNB->downlink_frequency[i];
|
||||
new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i];
|
||||
new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i];
|
||||
}
|
||||
|
||||
new_instance->uplink_frequency_offset[i] = x2ap_register_eNB->uplink_frequency_offset[i];
|
||||
new_instance->Nid_cell[i] = x2ap_register_eNB->Nid_cell[i];
|
||||
new_instance->N_RB_DL[i] = x2ap_register_eNB->N_RB_DL[i];
|
||||
new_instance->frame_type[i] = x2ap_register_eNB->frame_type[i];
|
||||
new_instance->fdd_earfcn_DL[i] = x2ap_register_eNB->fdd_earfcn_DL[i];
|
||||
new_instance->fdd_earfcn_UL[i] = x2ap_register_eNB->fdd_earfcn_UL[i];
|
||||
}
|
||||
|
||||
DevCheck(x2ap_register_eNB->nb_x2 <= X2AP_MAX_NB_ENB_IP_ADDRESS,
|
||||
|
||||
@@ -179,6 +179,7 @@ typedef struct x2ap_eNB_instance_s {
|
||||
uint32_t specialSubframe[MAX_NUM_CCs];
|
||||
|
||||
//#ifdef Rel15
|
||||
int32_t nr_band[MAX_NUM_CCs];
|
||||
uint32_t tdd_nRARFCN[MAX_NUM_CCs];
|
||||
int16_t nr_SCS[MAX_NUM_CCs];
|
||||
//#endif
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "x2ap_ids.h"
|
||||
|
||||
#include "x2ap_eNB_itti_messaging.h"
|
||||
#include "X2AP_SupportedSULFreqBandItem.h"
|
||||
|
||||
#include "msc.h"
|
||||
#include "assertions.h"
|
||||
@@ -1236,7 +1235,6 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(
|
||||
X2AP_En_gNB_ENDCX2SetupReqIEs_t *ie_GNB_ENDC;
|
||||
X2AP_PLMN_Identity_t *plmn;
|
||||
ServedNRcellsENDCX2ManagementList__Member *servedCellMember;
|
||||
X2AP_SupportedSULFreqBandItem_t *SULFreqBandItem;
|
||||
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
@@ -1284,8 +1282,8 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
|
||||
ie_GNB_ENDC->value.present = X2AP_En_gNB_ENDCX2SetupReqIEs__value_PR_ServedNRcellsENDCX2ManagementList;
|
||||
|
||||
{
|
||||
for (int i = 0; i<instance_p->num_cc; i++){
|
||||
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
|
||||
for (int i = 0; i<instance_p->num_cc; i++){
|
||||
servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)calloc(1,sizeof(ServedNRcellsENDCX2ManagementList__Member));
|
||||
{
|
||||
servedCellMember->servedNRCellInfo.nrpCI = instance_p->Nid_cell[i];
|
||||
|
||||
@@ -1299,60 +1297,63 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length
|
||||
NR_FIVEGS_TAC_ID_TO_BIT_STRING(instance_p->tac, servedCellMember->servedNRCellInfo.fiveGS_TAC);
|
||||
|
||||
X2AP_INFO("TAC: %d -> %02x%02x%02x\n", instance_p->tac,
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1],
|
||||
servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]);
|
||||
|
||||
plmn = (X2AP_PLMN_Identity_t *)calloc(1,sizeof(X2AP_PLMN_Identity_t));
|
||||
{
|
||||
MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.broadcastPLMNs.list, plmn);
|
||||
}
|
||||
|
||||
if (instance_p->frame_type[i] == TDD) {
|
||||
if (instance_p->frame_type[i] == TDD) {
|
||||
X2AP_FreqBandNrItem_t *freq_band;
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.present = X2AP_ServedNRCell_Information__nrModeInfo_PR_tdd;
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = 0; //instance_p->tdd_nRARFCN[i];
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.nRARFCN = instance_p->tdd_nRARFCN[i];
|
||||
/* addition of Frequency Band List */
|
||||
freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t));
|
||||
if (freq_band == NULL)
|
||||
exit(1);
|
||||
freq_band->freqBandIndicatorNr = instance_p->eutra_band[0];
|
||||
|
||||
SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t));
|
||||
SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */
|
||||
ASN_SEQUENCE_ADD(&freq_band->supportedSULBandList.list, SULFreqBandItem);
|
||||
freq_band->freqBandIndicatorNr = instance_p->nr_band[i];
|
||||
|
||||
ASN_SEQUENCE_ADD(&servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr, freq_band);
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
case 50:
|
||||
//This is not correct. Just to be able to test X2 only using an eNB instead of gNB
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb51;
|
||||
case 32:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb32;
|
||||
break;
|
||||
case 66:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb66;
|
||||
break;
|
||||
case 93 :
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
|
||||
break;
|
||||
case 106:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
|
||||
break;
|
||||
case 121:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
|
||||
break;
|
||||
case 217:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb217;
|
||||
break;
|
||||
case 273:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb273;
|
||||
break;
|
||||
/*More cases to be added */
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
case 93 :
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb93;
|
||||
break;
|
||||
case 106:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb106;
|
||||
break;
|
||||
case 121:
|
||||
servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nR_TxBW.nRNRB = X2AP_NRNRB_nrb121;
|
||||
break;
|
||||
/*More cases to be added */
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"ENDC_X2Setuprequest not supported for FDD!");
|
||||
}
|
||||
/*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
|
||||
INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
|
||||
/*Don't know where to extract the value of measurementTimingConfiguration from. Set it to 0 for now */
|
||||
INT8_TO_OCTET_STRING(0, &servedCellMember->servedNRCellInfo.measurementTimingConfiguration);
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list, servedCellMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list, ie_GNB_ENDC);
|
||||
|
||||
|
||||
@@ -1438,7 +1439,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
|
||||
}
|
||||
|
||||
if (instance_p->frame_type[i] == FDD) {
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_fDD;
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
@@ -1472,12 +1473,98 @@ int x2ap_eNB_generate_ENDC_x2_setup_response(
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertFatal(0,"X2Setupresponse not supported for TDD!");
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.present = X2AP_EUTRA_Mode_Info_PR_tDD;
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.eARFCN = instance_p->fdd_earfcn_DL[i];
|
||||
|
||||
switch (instance_p->subframeAssignment[i]) {
|
||||
case 0:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa0;
|
||||
break;
|
||||
case 1:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa1;
|
||||
break;
|
||||
case 2:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa2;
|
||||
break;
|
||||
case 3:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa3;
|
||||
break;
|
||||
case 4:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa4;
|
||||
break;
|
||||
case 5:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa5;
|
||||
break;
|
||||
case 6:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.subframeAssignment = X2AP_SubframeAssignment_sa6;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
||||
break;
|
||||
}
|
||||
switch (instance_p->specialSubframe[i]) {
|
||||
case 0:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp0;
|
||||
break;
|
||||
case 1:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp1;
|
||||
break;
|
||||
case 2:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp2;
|
||||
break;
|
||||
case 3:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp3;
|
||||
break;
|
||||
case 4:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp4;
|
||||
break;
|
||||
case 5:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp5;
|
||||
break;
|
||||
case 6:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp6;
|
||||
break;
|
||||
case 7:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp7;
|
||||
break;
|
||||
case 8:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.specialSubframePatterns = X2AP_SpecialSubframePatterns_ssp8;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for subframeAssignment");
|
||||
break;
|
||||
}
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixDL=X2AP_CyclicPrefixDL_normal;
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.specialSubframe_Info.cyclicPrefixUL=X2AP_CyclicPrefixUL_normal;
|
||||
|
||||
switch (instance_p->N_RB_DL[i]) {
|
||||
case 6:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw6;
|
||||
break;
|
||||
case 15:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw15;
|
||||
break;
|
||||
case 25:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw25;
|
||||
break;
|
||||
case 50:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw50;
|
||||
break;
|
||||
case 75:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw75;
|
||||
break;
|
||||
case 100:
|
||||
servedCellMember->servedEUTRACellInfo.eUTRA_Mode_Info.choice.tDD.transmission_Bandwidth = X2AP_Transmission_Bandwidth_bw100;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
|
||||
ASN_SEQUENCE_ADD(&ie_ENB_ENDC->value.choice.ServedEUTRAcellsENDCX2ManagementList.list, servedCellMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
ASN_SEQUENCE_ADD(&ie->value.choice.RespondingNodeType_EndcX2Setup.choice.respond_eNB.list, ie_ENB_ENDC);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user