Commit 03e5b461 authored by hardy's avatar hardy

Merge remote-tracking branch 'origin/NR_MAC_SSB_RO_GlobalEdge' into integration_2020_wk42

Solved Conflicts in:
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
	openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
	openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
parents 8eb9d0b4 63ddc9ac
......@@ -179,7 +179,7 @@ void prach_eNB_tosplit(uint8_t *bufferZone, int bufSize, PHY_VARS_eNB *eNB, L1_r
ru=eNB->RU_list[i];
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
int ce_level;
for (ce_level=0; ce_level<4; ce_level++)
......
......@@ -228,7 +228,7 @@ void init_eNB_afterRU(void) {
for (int i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i];
for (int ce_level=0; ce_level<4; ce_level++)
eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];
......@@ -483,7 +483,7 @@ void prach_procedures_ocp(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, int br_flag)
ru=eNB->RU_list[i];
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
int ce_level;
if (br_flag==1)
......
......@@ -255,11 +255,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
// Do PRACH RU processing
int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST);
if (prach_id>=0) {
L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu);
gNB->prach_vars.list[prach_id].frame=-1;
}
L1_nr_prach_procedures(gNB,frame_rx,slot_rx);
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
......@@ -981,7 +977,7 @@ void init_eNB_afterRU(void) {
for (i=0; i<gNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[i];
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i];
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
}
}
......
......@@ -1594,13 +1594,36 @@ void *ru_thread( void *param ) {
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
// Do PRACH RU processing
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
uint8_t prachStartSymbol,N_dur;
if (prach_id>=0) {
rx_nr_prach_ru(ru,
ru->prach_list[prach_id].fmt,
ru->prach_list[prach_id].numRA,
ru->prach_list[prach_id].prachStartSymbol,
proc->frame_rx,proc->tti_rx);
N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
/*
get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value,
proc->frame_rx,proc->tti_rx,
ru->config.carrier_config.dl_frequency.value,
fp->numerology_index,
fp->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
*/
for (int prach_oc = 0; prach_oc<ru->prach_list[prach_id].num_prach_ocas; prach_oc++) {
prachStartSymbol = ru->prach_list[prach_id].prachStartSymbol+prach_oc*N_dur;
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
rx_nr_prach_ru(ru,
ru->prach_list[prach_id].fmt, //could also use format
ru->prach_list[prach_id].numRA,
prachStartSymbol,
prach_oc,
proc->frame_rx,proc->tti_rx);
}
free_nr_ru_prach_entry(ru,prach_id);
}
}
......
......@@ -321,6 +321,7 @@ typedef enum {
#define NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG 0x1012
#define NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG 0x1013
#define NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG 0x1014
#define NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG 0x1029
#define NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG 0x1015
#define NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG 0x1016
#define NFAPI_NR_CONFIG_K1_TAG 0x1017
......@@ -385,7 +386,6 @@ typedef struct
typedef struct
{
uint8_t num_prach_fd_occasions;
nfapi_uint16_tlv_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
nfapi_uint8_tlv_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
nfapi_uint16_tlv_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
......@@ -401,7 +401,9 @@ typedef struct
nfapi_uint8_tlv_t prach_sub_c_spacing;//Subcarrier spacing of PRACH. [38.211 sec 4.2] Value:0->4
nfapi_uint8_tlv_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
nfapi_uint8_tlv_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
nfapi_uint8_tlv_t prach_ConfigurationIndex;//PRACH configuration index. Value:0->255
nfapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
nfapi_uint8_tlv_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
nfapi_uint8_tlv_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
......
......@@ -121,13 +121,13 @@ int phy_init_RU(RU_t *ru) {
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
//AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
//"nb_antennas_rx too large");
ru->prach_rxsigF = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
ru->prach_rxsigF[0] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
for (j=0; j<4; j++) ru->prach_rxsigF_br[j] = (int16_t **)malloc(ru->nb_rx * sizeof(int16_t *));
for (i=0; i<ru->nb_rx; i++) {
ru->prach_rxsigF[i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
ru->prach_rxsigF[0][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[0][i]);
for (j=0; j<4; j++) {
ru->prach_rxsigF_br[j][i] = (int16_t *)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
......@@ -230,14 +230,14 @@ void phy_free_RU(RU_t *ru) {
}
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[i]);
free_and_zero(ru->prach_rxsigF[0][i]);
for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]);
}
for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j]);
free_and_zero(ru->prach_rxsigF);
free_and_zero(ru->prach_rxsigF[0]);
/* ru->prach_rxsigF_br is not allocated -> don't free */
for (i = 0; i < RC.nb_L1_inst; i++) {
......
......@@ -497,11 +497,12 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
fd_occasion = 0;
nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config;
short_sequence = prach_config->prach_sequence_length.value;
// for(fd_occasion = 0; fd_occasion <= prach_config->num_prach_fd_occasions.value ; fd_occasion) { // TODO Need to handle for msg1-fdm > 1
num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value;
rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value;
compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u);
// }
RC.gNB[Mod_id]->configured = 1;
init_symbol_rotation(fp,fp->dl_CarrierFreq);
......
......@@ -107,12 +107,14 @@ int nr_phy_init_RU(RU_t *ru) {
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
// AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]),
// "nb_antennas_rx too large");
ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; i<ru->nb_rx; i++) {
// largest size for PRACH FFT is 4x98304 (16*24576)
ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]);
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
ru->prach_rxsigF[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*));
for (i=0; i<ru->nb_rx; i++) {
// largest size for PRACH FFT is 4x98304 (16*24576)
ru->prach_rxsigF[j][i] = (int16_t*)malloc16_clear( 4*98304*2*sizeof(int16_t) );
LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[j][i]);
}
}
AssertFatal(RC.nb_nr_L1_inst <= NUMBER_OF_eNB_MAX,"gNB instances %d > %d\n",
......@@ -186,10 +188,12 @@ void nr_phy_free_RU(RU_t *ru)
for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdataF[i]);
free_and_zero(ru->common.rxdataF);
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[i]);
for (j=0;j<NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX;j++) {
for (i = 0; i < ru->nb_rx; i++) {
free_and_zero(ru->prach_rxsigF[j][i]);
}
}
for (i = 0; i < RC.nb_nr_L1_inst; i++) {
for (p = 0; p < 15; p++) {
for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]);
......
......@@ -49,7 +49,7 @@ void send_IF4p5(RU_t *ru,
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
int16_t **prach_rxsigF = ru->prach_rxsigF[0];
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
void *tx_buffer = ru->ifbuffer.tx[subframe&1];
void *tx_buffer_prach = ru->ifbuffer.tx_prach;
......@@ -276,7 +276,7 @@ void recv_IF4p5(RU_t *ru,
LTE_DL_FRAME_PARMS *fp = ru->frame_parms;
int32_t **txdataF = ru->common.txdataF_BF;
int32_t **rxdataF = ru->common.rxdataF;
int16_t **prach_rxsigF = ru->prach_rxsigF;
int16_t **prach_rxsigF = ru->prach_rxsigF[0];
int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br;
void *rx_buffer = ru->ifbuffer.rx;
uint16_t element_id;
......
......@@ -167,7 +167,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
br_flag,ce_level,frame_prach,subframe,fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[ce_level],prach_ConfigIndex);
}
} else {
rxsigF = ru->prach_rxsigF;
rxsigF = ru->prach_rxsigF[0];
if (LOG_DEBUGFLAG(PRACH)) {
if (((frame_prach)&1023) < 20) LOG_I(PHY,"PRACH (RU) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d\n",
......
This diff is collapsed.
......@@ -288,6 +288,7 @@ void nr_fill_prach(PHY_VARS_gNB *gNB,
void rx_nr_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu,
int prachOccasion,
int frame,
int subframe,
uint16_t *max_preamble,
......@@ -298,6 +299,7 @@ void rx_nr_prach_ru(RU_t *ru,
int prach_fmt,
int numRA,
int prachStartSymbol,
int prachOccasion,
int frame,
int subframe);
......@@ -306,7 +308,7 @@ void nr_fill_prach_ru(RU_t *ru,
int Slot,
nfapi_nr_prach_pdu_t *prach_pdu);
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type);
int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, find_type_t type);
int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type);
NR_gNB_PUCCH_t *new_gNB_pucch(void);
......@@ -325,7 +327,7 @@ int nr_find_pucch(uint16_t rnti,
void init_prach_list(PHY_VARS_gNB *gNB);
void init_prach_ru_list(RU_t *ru);
void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
void nr_decode_pucch1(int32_t **rxdataF,
pucch_GroupHopping_t pucch_GroupHopping,
......
This diff is collapsed.
......@@ -191,9 +191,11 @@ typedef struct {
int fmt;
int numRA;
int prachStartSymbol;
int num_prach_ocas;
} RU_PRACH_list_t;
#define NUMBER_OF_NR_RU_PRACH_MAX 8
#define NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX 12
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
......@@ -594,8 +596,8 @@ typedef struct RU_t_s {
RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX];
/// mutex for prach_list access
pthread_mutex_t prach_list_mutex;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF;
/// received frequency-domain signal for PRACH (IF4p5 RRU)
int16_t **prach_rxsigF[NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX];
/// received frequency-domain signal for PRACH BR (IF4p5 RRU)
int16_t **prach_rxsigF_br[4];
/// sequence number for IF5
......
......@@ -80,7 +80,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
ru=eNB->RU_list[i];
for (ru_aa=0,aa=0; ru_aa<ru->nb_rx; ru_aa++,aa++) {
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[0][ru_aa];
int ce_level;
if (br_flag==1)
......
......@@ -52,87 +52,114 @@ extern uint8_t nfapi_mode;
extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,
nfapi_nr_prach_pdu_t *prach_pdu) {
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0};
uint16_t i;
gNB->UL_INFO.rach_ind.number_of_pdus=0;
uint8_t pdu_index = 0;
RU_t *ru;
int aa=0;
int ru_aa;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1);
gNB->UL_INFO.rach_ind.sfn = frame;
gNB->UL_INFO.rach_ind.slot = slot;
gNB->UL_INFO.rach_ind.pdu_list = gNB->prach_pdu_indication_list;
gNB->UL_INFO.rach_ind.number_of_pdus = 0;
ru=gNB->RU_list[0];
for (i=0;i<gNB->num_RU;i++) {
ru=gNB->RU_list[i];
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[i]->prach_rxsigF[ru_aa];
}
}
rx_nr_prach(gNB,
prach_pdu,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]
);
LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
frame,slot,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_delay[0],
gNB->prach_energy_counter);
if ((gNB->prach_energy_counter == 100) &&
(max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
gNB->Mod_id,
frame,
slot,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_energy[0]%10,
max_preamble_delay[0]);
T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
int prach_id=find_nr_prach(gNB,frame,slot,SEARCH_EXIST);
if (prach_id>=0) {
nfapi_nr_prach_pdu_t *prach_pdu = &gNB->prach_vars.list[prach_id].pdu;
uint8_t prachStartSymbol;
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
gNB->UL_INFO.rach_ind.number_of_pdus = 1;
gNB->UL_INFO.rach_ind.pdu_list = &gNB->prach_pdu_indication_list[0];
gNB->UL_INFO.rach_ind.sfn = frame;
gNB->UL_INFO.rach_ind.slot = slot;
/*
uint16_t format,RA_sfn_index;
uint8_t start_symbol,N_t_slot,N_dur,N_RA_slot,config_period;
get_nr_prach_info_from_index(gNB->gNB_config.prach_config.prach_ConfigurationIndex.value,
frame,slot,
gNB->gNB_config.carrier_config.dl_frequency.value,
gNB->frame_parms.numerology_index,
gNB->frame_parms.frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
*/
gNB->prach_pdu_indication_list[0].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
gNB->prach_pdu_indication_list[0].symbol_index = prach_pdu->prach_start_symbol; // FIXME to be changed for multi-ssb (this is only the start symbol of first occasion)
gNB->prach_pdu_indication_list[0].slot_index = slot;
gNB->prach_pdu_indication_list[0].freq_index = prach_pdu->num_ra;
gNB->prach_pdu_indication_list[0].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
gNB->prach_pdu_indication_list[0].avg_snr = 0xff; // invalid for now
gNB->prach_pdu_indication_list[0].num_preamble = 1;
gNB->prach_pdu_indication_list[0].preamble_list = gNB->preamble_list;
gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_index = max_preamble[0];
gNB->prach_pdu_indication_list[0].preamble_list[0].timing_advance = max_preamble_delay[0];
gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_pwr = 0xffffffff;
}
gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10);
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) {
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa];
}
prachStartSymbol = prach_pdu->prach_start_symbol+prach_oc*N_dur;
//comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}.
rx_nr_prach(gNB,
prach_pdu,
prach_oc,
frame,
slot,
&max_preamble[0],
&max_preamble_energy[0],
&max_preamble_delay[0]
);
free_nr_prach_entry(gNB,prach_id);
LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n",
frame,slot,prach_oc,prachStartSymbol,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_delay[0],
gNB->prach_energy_counter);
if ((gNB->prach_energy_counter == 100) &&
(max_preamble_energy[0] > gNB->measurements.prach_I0+100)) {
LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n",
gNB->Mod_id,
frame,
slot,
max_preamble[0],
max_preamble_energy[0]/10,
max_preamble_energy[0]%10,
max_preamble_delay[0],
prachStartSymbol,
prach_pdu->num_ra);
T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot),
T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
gNB->UL_INFO.rach_ind.number_of_pdus += 1;
gNB->prach_pdu_indication_list[pdu_index].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value;
gNB->prach_pdu_indication_list[pdu_index].symbol_index = prachStartSymbol;
gNB->prach_pdu_indication_list[pdu_index].slot_index = slot;
gNB->prach_pdu_indication_list[pdu_index].freq_index = prach_pdu->num_ra;
gNB->prach_pdu_indication_list[pdu_index].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254;
gNB->prach_pdu_indication_list[pdu_index].avg_snr = 0xff; // invalid for now
gNB->prach_pdu_indication_list[pdu_index].num_preamble = 1;
gNB->prach_pdu_indication_list[pdu_index].preamble_list = gNB->preamble_list;
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_index = max_preamble[0];
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].timing_advance = max_preamble_delay[0];
gNB->prach_pdu_indication_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff;
pdu_index++;
}
gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10);
if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10);
if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++;
} //if prach_id>0
} //for NUMBER_OF_NR_PRACH_OCCASION_MAX
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0);
}
......@@ -39,7 +39,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas);
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_prach_pdu_t *prach_pdu);
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
......
......@@ -113,6 +113,10 @@ int main(int argc, char **argv){
uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1;
uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB;
uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000;
uint16_t RA_sfn_index;
uint8_t N_RA_slot;
uint8_t config_period;
int prachOccasion = 0;
double DS_TDL = .03;
// int8_t interf1=-19,interf2=-19;
......@@ -428,15 +432,18 @@ int main(int argc, char **argv){
gNB->proc.slot_rx = slot;
int ret = get_nr_prach_info_from_index(config_index,
(int)frame,
(int)slot_gNB,
absoluteFrequencyPointA,
mu,
frame_parms->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur);
(int)frame,
(int)slot_gNB,
absoluteFrequencyPointA,
mu,
frame_parms->frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
if (ret == 0) {printf("No prach in %d.%d, mu %d, config_index %d\n",frame,slot,mu,config_index); exit(-1);}
format0 = format&0xff; // first column of format from table
......@@ -445,60 +452,54 @@ int main(int argc, char **argv){
if (format1 != 0xff) {
switch(format0) {
case 0xa1:
prach_format = 9;
prach_format = 11;
break;
case 0xa2:
prach_format = 10;
prach_format = 12;
break;
case 0xa3:
prach_format = 11;
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 0xa1:
prach_format = 0;
break;
case 0xa2:
prach_format = 1;
break;
case 0xa3:
prach_format = 2;
break;
case 0xb1:
prach_format = 3;
break;
case 0xb2:
prach_format = 4;
break;
case 0xb3:
prach_format = 5;
break;
case 0xb4:
prach_format = 6;
break;
case 0xc0:
prach_format = 7;
break;
case 0xc2:
prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
break;
case 3:
// long formats are handled @ PHY
break;
switch(format0) { // single PRACH format
case 0:
prach_format = 0;
break;
case 1:
prach_format = 1;
break;
case 2:
prach_format = 2;
break;
case 3:
prach_format = 3;
break;
case 0xa1:
prach_format = 4;
break;
case 0xa2:
prach_format = 5;
break;
case 0xa3:
prach_format = 6;
break;
case 0xb1:
prach_format = 7;
break;
case 0xb4:
prach_format = 8;
break;
case 0xc0:
prach_format = 9;
break;
case 0xc2:
prach_format = 10;
break;
default:
AssertFatal(1==0, "Invalid PRACH format");
AssertFatal(1 == 0, "Invalid PRACH format");
}
}
......@@ -721,11 +722,11 @@ int main(int argc, char **argv){
}
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, slot);
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot);
gNB->prach_vars.rxsigF = ru->prach_rxsigF;
gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion];
if (n_frames == 1) printf("ncs %d,num_seq %d\n",prach_pdu->num_cs, prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value);
rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
rx_nr_prach(gNB, prach_pdu, prachOccasion, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay);
// printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx);
......
......@@ -153,7 +153,7 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_RACH_ConfigCommon_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->present = NR_SetupRelease_RACH_ConfigCommon_PR_setup;
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon));
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles = CALLOC(1,sizeof(long));
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles = CALLOC(1,sizeof(long));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB));
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->groupBconfigured = CALLOC(1,sizeof(struct NR_RACH_ConfigCommon__groupBconfigured));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB = CALLOC(1,sizeof(NR_RSRP_Range_t));
......
......@@ -99,7 +99,24 @@ int get_nr_prach_info_from_index(uint8_t index,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur);
uint8_t *N_dur,
uint16_t *RA_sfn_index,
uint8_t *N_RA_slot,
uint8_t *config_period);
int get_nr_prach_occasion_info_from_index(uint8_t index,
uint32_t pointa,
uint8_t mu,
uint8_t unpaired,
uint16_t *format,
uint8_t *start_symbol,
uint8_t *N_t_slot,
uint8_t *N_dur,
uint8_t *N_RA_slot,
uint16_t *N_RA_sfn,
uint8_t *max_association_period);
uint8_t get_nr_prach_duration(uint8_t prach_format);
uint8_t get_pusch_mcs_table(long *mcs_Table,
int is_tp,
......@@ -125,4 +142,5 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
#endif
......@@ -1073,6 +1073,9 @@ void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac,
void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
uint8_t config_index, mu, N_dur, N_t_slot, start_symbol;
uint16_t RA_sfn_index;
uint8_t N_RA_slot;
uint8_t config_period;
uint16_t format, format0, format1, ncs;
int msg1_FDM, is_nr_prach_slot, fdm;
......@@ -1109,7 +1112,10 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
&format,
&start_symbol,
&N_t_slot,
&N_dur);
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
if (is_nr_prach_slot && mac->ra_state == RA_UE_IDLE) {
......@@ -1156,57 +1162,51 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
if (format1 != 0xff) {
switch(format0) { // dual PRACH format
case 0xa1:
prach_config_pdu->prach_format = 9;
prach_config_pdu->prach_format = 11;
break;
case 0xa2:
prach_config_pdu->prach_format = 10;
prach_config_pdu->prach_format = 12;
break;
case 0xa3:
prach_config_pdu->prach_format = 11;
prach_config_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) { // single PRACH format
case 0xa1:
case 0:
prach_config_pdu->prach_format = 0;
break;
case 0xa2:
case 1:
prach_config_pdu->prach_format = 1;
break;
case 0xa3:
case 2:
prach_config_pdu->prach_format = 2;
break;
case 0xb1:
case 3:
prach_config_pdu->prach_format = 3;
break;
case 0xb2:
case 0xa1:
prach_config_pdu->prach_format = 4;
break;
case 0xb3:
case 0xa2:
prach_config_pdu->prach_format = 5;
break;
case 0xb4:
case 0xa3:
prach_config_pdu->prach_format = 6;
break;
case 0xc0:
case 0xb1:
prach_config_pdu->prach_format = 7;
break;
case 0xc2:
case 0xb4:
prach_config_pdu->prach_format = 8;
break;
case 0:
// long formats are handled @ PHY
break;
case 1:
// long formats are handled @ PHY
break;
case 2:
// long formats are handled @ PHY
case 0xc0:
prach_config_pdu->prach_format = 9;
break;
case 3:
// long formats are handled @ PHY
case 0xc2:
prach_config_pdu->prach_format = 10;
break;
default:
AssertFatal(1 == 0, "Invalid PRACH format");
......
......@@ -150,6 +150,10 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->ssb_config.ss_pbch_power.tl.tag = NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG;
cfg->num_tlv++;
cfg->ssb_config.bch_payload.value = 1;
cfg->ssb_config.bch_payload.tl.tag = NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG;
cfg->num_tlv++;
cfg->ssb_config.scs_common.value = *scc->ssbSubcarrierSpacing;
cfg->ssb_config.scs_common.tl.tag = NFAPI_NR_CONFIG_SCS_COMMON_TAG;
cfg->num_tlv++;
......@@ -173,6 +177,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.restricted_set_config.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig;
cfg->prach_config.restricted_set_config.tl.tag = NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG;
cfg->num_tlv++;
cfg->prach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
cfg->prach_config.prach_ConfigurationIndex.tl.tag = NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG;
cfg->num_tlv++;
switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) {
case 0 :
......@@ -193,26 +200,30 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm
cfg->prach_config.num_prach_fd_occasions.tl.tag = NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG;
cfg->num_tlv++;
cfg->prach_config.prach_ConfigurationIndex.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
cfg->prach_config.prach_ConfigurationIndex.tl.tag = NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions.value*sizeof(nfapi_nr_num_prach_fd_occasions_t));
for (i=0; i<cfg->prach_config.num_prach_fd_occasions.value; i++) {
cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
// cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i;
if (cfg->prach_config.prach_sequence_length.value)
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
else
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.tl.tag = NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
//k1= msg1_FrequencyStart + 12 (no. of FDM)(RB for PRACH occasion);
cfg->prach_config.num_prach_fd_occasions_list[i].k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
cfg->num_tlv++;
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);
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 = ???
cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = 1;
}
cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
......@@ -344,7 +355,10 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
phycfg.cfg->num_tlv++;
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
find_SSB_and_RO_available(Mod_idP);
}
if (secondaryCellGroup) {
......
......@@ -54,6 +54,7 @@
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
extern uint8_t SSB_Table[38];
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
......@@ -66,15 +67,24 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
int mib_sdu_length;
int CC_id;
AssertFatal(slotP == 0, "Subframe must be 0\n");
AssertFatal((frameP & 7) == 0, "Frame must be a multiple of 8\n");
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
dl_tti_request = &gNB->DL_req[CC_id];
dl_req = &dl_tti_request->dl_tti_request_body;
cc = &gNB->common_channels[CC_id];
#if 0
//SSB is transmitted based on SSB periodicity
if((frameP % cfg->ssb_table.ssb_period.value) == 0) {
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 ssb_index = -1;
for (int i=0; i<2; i++) { // max two SSB per slot
ssb_index = i + SSB_Table[slotP]; // computing the ssb_index
if ((ssb_index<64) && ((L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
#endif
mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]); // not used in this case
......@@ -96,7 +106,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
AssertFatal(cc->ServingCellConfigCommon->physCellId!=NULL,"cc->ServingCellConfigCommon->physCellId is null\n");
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *cc->ServingCellConfigCommon->physCellId;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;//ssb_index ;//SSB index for each SSB
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
AssertFatal(cc->ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
......@@ -132,8 +142,8 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
default:
AssertFatal(1==0,"SCS %ld not allowed for SSB \n", *cc->ServingCellConfigCommon->ssbSubcarrierSpacing);
}
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = 0; //kSSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10;/*cfg->ssb_table.ssb_offset_point_a.value;*/ // absoluteFrequencySSB is the center of SSB
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
dl_req->nPDUs++;
......
......@@ -1640,6 +1640,25 @@ void set_Y(int Y[3][160], rnti_t rnti) {
}
}
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP) {
//------------------------------------------------------------------------------
int RA_id;
RA_t *ra = (RA_t *) &RC.nrmac[mod_idP]->common_channels[CC_idP].ra[0];
for (RA_id = 0; RA_id < NB_RA_PROC_MAX; RA_id++) {
LOG_D(MAC, "Checking RA_id %d for %x : state %d\n",
RA_id,
rntiP,
ra[RA_id].state);
if (ra[RA_id].state != IDLE && ra[RA_id].rnti == rntiP)
return RA_id;
}
return -1;
}
//------------------------------------------------------------------------------
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
......
......@@ -401,5 +401,45 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
}
else if (sduP != NULL) { // if the CRC passed
// random access pusch with TC-RNTI
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0];
if (ra->state != WAIT_Msg3) {
LOG_E(MAC,
"expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n",
WAIT_Msg3,
ra->state,
ra->rnti);
return;
}
if (ra->rnti != current_rnti) {
LOG_E(MAC,
"expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n",
ra->rnti,
ra->crnti,
current_rnti);
return;
}
free(ra->preambles.preamble_list);
ra->state = RA_IDLE;
LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti);
UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
UE_info->UE_beam_index[UE_id] = ra->beam_id;
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
AssertFatal(bwpList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n",
bwpList->list.count);
const int bwp_id = 1;
UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
LOG_W(MAC,
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
"adding UE MAC Context UE_id %d/RNTI %04x\n",
gnb_mod_idP,
current_rnti,
UE_id,
ra->crnti);
}
}
......@@ -306,6 +306,8 @@ void add_nr_ue_list(NR_UE_list_t *listP, int UE_id);
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP);
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP);
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
......@@ -387,5 +389,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
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);
int16_t ssb_index_from_prach(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
uint16_t preamble_index,
uint8_t freq_index,
uint8_t symbol);
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__*/
......@@ -74,6 +74,7 @@
#define MAX_NUM_CCE 90
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#define MAX_NUM_OF_SSB 64
typedef enum {
RA_IDLE = 0,
......@@ -146,6 +147,8 @@ typedef struct {
int msg4_mcs;
/// RA search space
NR_SearchSpace_t *ra_ss;
// Beam index
uint8_t beam_id;
/// secondaryCellGroup for UE in NSA that is to come
NR_CellGroupConfig_t *secondaryCellGroup;
/// Preambles for contention-free access
......@@ -190,6 +193,16 @@ typedef struct {
uint8_t vrb_map_UL[275];
/// number of subframe allocation pattern available for MBSFN sync area
uint8_t num_sf_allocation_pattern;
///Number of active SSBs
uint8_t num_active_ssb;
//Total available prach occasions per configuration period
uint32_t total_prach_occasions_per_config_period;
//Total available prach occasions
uint32_t total_prach_occasions;
//Max Association period
uint8_t max_association_period;
//SSB index
uint8_t ssb_index[MAX_NUM_OF_SSB];
} NR_COMMON_channels_t;
......@@ -386,6 +399,8 @@ typedef struct {
int Y[MAX_MOBILES_PER_GNB][3][160];
int m[MAX_MOBILES_PER_GNB];
int num_pdcch_cand[MAX_MOBILES_PER_GNB][MAX_NUM_CORESET];
// UE selected beam index
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
} NR_UE_info_t;
/*! \brief top level eNB MAC structure */
......
......@@ -56,24 +56,25 @@ extern uint16_t sf_ahead;
extern uint16_t sl_ahead;
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.number_of_pdus>0) {
AssertFatal(UL_info->rach_ind.number_of_pdus==1,"More than 1 RACH pdu not supported\n");
UL_info->rach_ind.number_of_pdus=0;
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
if (UL_info->rach_ind.pdu_list[0].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1,
"More than 1 preamble not supported\n");
if (UL_info->rach_ind.number_of_pdus>0) {
LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
int npdus = UL_info->rach_ind.number_of_pdus;
for(int i = 0; i < npdus; i++) {
UL_info->rach_ind.number_of_pdus--;
if (UL_info->rach_ind.pdu_list[i].num_preamble>0)
AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1,
"More than 1 preamble not supported\n");
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[0].freq_index,
UL_info->rach_ind.pdu_list[0].symbol_index,
UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance);
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
UL_info->rach_ind.sfn,
UL_info->rach_ind.slot,
UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index,
UL_info->rach_ind.pdu_list[i].freq_index,
UL_info->rach_ind.pdu_list[i].symbol_index,
UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance);
}
}
}
......
......@@ -174,10 +174,41 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
struct NR_CFRA_SSB_Resource *ssbElem = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem->ssb = 0;
ssbElem->ra_PreambleIndex= 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem);
struct NR_CFRA_SSB_Resource *ssbElem[8];
ssbElem[0] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[0]->ssb = 0;
ssbElem[0]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[0]);
#if 0
ssbElem[1] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[1]->ssb = 1;
ssbElem[1]->ra_PreambleIndex = 62;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[1]);
ssbElem[2] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[2]->ssb = 2;
ssbElem[2]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[2]);
ssbElem[3] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[3]->ssb = 3;
ssbElem[3]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[3]);
ssbElem[4] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[4]->ssb = 4;
ssbElem[4]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[4]);
ssbElem[5] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[5]->ssb = 5;
ssbElem[5]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[5]);
ssbElem[6] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[6]->ssb = 6;
ssbElem[6]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[6]);
ssbElem[7] = calloc(1,sizeof(struct NR_CFRA_SSB_Resource));
ssbElem[7]->ssb = 7;
ssbElem[7]->ra_PreambleIndex = 63;
ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[7]);
#endif
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants));
secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup;
......
......@@ -1177,7 +1177,7 @@ void init_eNB_afterRU(void) {
for (i=0; i<eNB->RU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i];
eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[0][i];
for (int ce_level=0; ce_level<4; ce_level++)
eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment