Commit c6a04db9 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_UE_PUCCH_fixes' into integration_2023_w15

parents 8292c452 a85fee5d
......@@ -356,9 +356,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
mac->scc->tdd_UL_DL_ConfigurationCommon :
mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
ul_info.slot_tx, mac->frame_type)) {
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() and nr_ue_pucch_scheduler() from %s\n", ul_info.slot_tx, __FUNCTION__);
LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind()\n", ul_info.slot_tx);
nr_ue_ul_scheduler(&ul_info);
nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL);
}
process_queued_nr_nfapi_msgs(mac, sfn_slot);
}
......
......@@ -255,7 +255,6 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
pdu_0_1->ul_cqi = 255;
pdu_0_1->timing_advance = 0;
pdu_0_1->rssi = 0;
if (mac->nr_ue_emul_l1.num_harqs > 0) {
int harq_index = 0;
pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR
......
......@@ -4651,29 +4651,32 @@ void find_period_offset_SR(const NR_SchedulingRequestResourceConfig_t *Schedulin
}
}
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_tot,
uint16_t O_csi,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
uint8_t n_re_ctrl) {
uint16_t O_crc;
if (O_tot<12)
O_crc = 0;
int compute_pucch_crc_size(int O_uci)
{
if (O_uci < 12)
return 0;
else{
if (O_tot<20)
O_crc = 6;
if (O_uci < 20)
return 6;
else {
if (O_tot<360)
O_crc = 11;
if (O_uci < 360)
return 11;
else
AssertFatal(1==0,"Case for segmented PUCCH not yet implemented");
}
}
}
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_uci,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
uint8_t n_re_ctrl)
{
int O_crc = compute_pucch_crc_size(O_uci);
int O_tot = O_uci + O_crc;
int rtimes100;
switch(*maxCodeRate){
......@@ -4704,25 +4707,27 @@ uint16_t compute_pucch_prb_size(uint8_t format,
float r = (float)rtimes100/100;
if (O_csi == O_tot) {
if ((O_tot+O_csi)>(nr_prbs*n_re_ctrl*n_symb*Qm*r))
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
r,O_tot,O_crc,nr_prbs);
}
AssertFatal(O_tot <= (nr_prbs * n_re_ctrl * n_symb * Qm * r),
"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with %d PRBs",
r,
O_tot,
O_crc,
nr_prbs);
if (format==2){
// TODO fix this for multiple CSI reports
for (int i=1; i<=nr_prbs; i++){
if((O_tot+O_crc)<=(i*n_symb*Qm*n_re_ctrl*r) &&
(O_tot+O_crc)>((i-1)*n_symb*Qm*n_re_ctrl*r))
for (int i = nr_prbs; i > 0; i--) {
// compute code rate factor for next prb value
int next_prb_factor = (i - 1) * n_symb * Qm * n_re_ctrl * r;
// if it does not sa
if (O_tot > next_prb_factor)
return i;
}
AssertFatal(1==0,"MaxCodeRate %.2f can't support %d UCI bits and %d CRC bits with at most %d PRBs",
r,O_tot,O_crc,nr_prbs);
}
else{
AssertFatal(1==0,"Not yet implemented");
}
return 0;
}
int get_dlbw_tbslbrm(int scc_bwpsize,
......
......@@ -171,7 +171,7 @@ int64_t *get_prach_config_info(frequency_range_t freq_range,
uint8_t unpaired);
uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config);
int compute_pucch_crc_size(int O_uci);
uint8_t get_l0_ul(uint8_t mapping_type, uint8_t dmrs_typeA_position);
int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmrs_AdditionalPosition_t additional_pos, pusch_maxLength_t pusch_maxLength, uint8_t start_symbolt, uint8_t dmrs_typeA_position);
......@@ -238,8 +238,7 @@ uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config,
uint16_t compute_pucch_prb_size(uint8_t format,
uint8_t nr_prbs,
uint16_t O_tot,
uint16_t O_csi,
uint16_t O_uci,
NR_PUCCH_MaxCodeRate_t *maxCodeRate,
uint8_t Qm,
uint8_t n_symb,
......
......@@ -336,7 +336,6 @@ typedef struct {
bool ack_received;
uint8_t pucch_resource_indicator;
uint16_t feedback_to_ul;
int is_common;
frame_t dl_frame;
int dl_slot;
uint8_t ack;
......@@ -356,19 +355,18 @@ typedef struct {
} RAR_grant_t;
typedef struct {
int n_HARQ_ACK;
NR_PUCCH_Resource_t *pucch_resource;
uint32_t ack_payload;
uint8_t sr_payload;
uint32_t csi_part1_payload;
uint32_t csi_part2_payload;
int resource_indicator;
int resource_set_id;
int is_common;
int initial_pucch_id;
NR_PUCCH_Resource_t *pucch_resource;
int n_sr;
int n_csi;
int n_harq;
int n_CCE;
int N_CCE;
int8_t delta_pucch;
int delta_pucch;
int initial_pucch_id;
} PUCCH_sched_t;
typedef struct {
......
......@@ -197,10 +197,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot);
uint8_t nr_get_csi_measurements(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot,
PUCCH_sched_t *pucch);
int nr_get_csi_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch,
......@@ -276,49 +273,39 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
uint8_t dai,
int n_CCE,
int N_CCE,
int is_common,
frame_t frame,
int slot);
uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac,
frame_t frame,
int slot,
PUCCH_sched_t *pucch);
bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch);
int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size);
void select_pucch_resource(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch);
void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int scs,
NR_PUCCH_Config_t *pucch_Config,
PUCCH_sched_t *pucch,
int delta_pucch,
uint8_t format_type,
uint16_t nb_of_prbs,
uint8_t freq_hop_flag,
uint8_t add_dmrs_flag,
uint8_t freq_hop_flag,
uint8_t add_dmrs_flag,
uint8_t N_symb_PUCCH,
int subframe_number,
int O_ACK, int O_SR,
int O_CSI, int O_CRC);
int O_uci);
int get_deltatf(uint16_t nb_of_prbs,
uint8_t N_symb_PUCCH,
uint8_t freq_hop_flag,
uint8_t add_dmrs_flag,
int N_sc_ctrl_RB,
int n_HARQ_ACK,
int O_ACK, int O_SR,
int O_CSI, int O_CRC);
int O_UCI);
void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int slot,
uint16_t rnti,
PUCCH_sched_t *pucch,
fapi_nr_ul_config_pucch_pdu *pucch_pdu,
int O_SR, int O_ACK, int O_CSI);
fapi_nr_ul_config_pucch_pdu *pucch_pdu);
/* Random Access */
......
......@@ -2197,87 +2197,80 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) {
LOG_D(NR_MAC,"Map SSB to RO done\n");
}
void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, void *phy_data) {
void nr_ue_pucch_scheduler(module_id_t module_idP, frame_t frameP, int slotP, void *phy_data)
{
NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
int O_SR = 0;
int O_ACK = 0;
int O_CSI = 0;
int N_UCI = 0;
PUCCH_sched_t pucch = {
.resource_indicator = -1,
.initial_pucch_id = -1
};
uint16_t rnti = mac->crnti; //FIXME not sure this is valid for all pucch instances
PUCCH_sched_t pucch[3] = {0}; // TODO the size might change in the future in case of multiple SR or multiple CSI in a slot
mac->nr_ue_emul_l1.num_srs = 0;
mac->nr_ue_emul_l1.num_harqs = 0;
mac->nr_ue_emul_l1.num_csi_reports = 0;
int num_res = 0;
// SR
if (mac->state == UE_CONNECTED && trigger_periodic_scheduling_request(mac, &pucch, frameP, slotP)) {
O_SR = 1;
if (mac->state == UE_CONNECTED && trigger_periodic_scheduling_request(mac, &pucch[0], frameP, slotP)) {
num_res++;
/* sr_payload = 1 means that this is a positive SR, sr_payload = 0 means that it is a negative SR */
pucch.sr_payload = nr_ue_get_SR(module_idP,
frameP,
slotP);
pucch[0].sr_payload = nr_ue_get_SR(module_idP, frameP, slotP);
}
// CSI
int csi_res = 0;
if (mac->state == UE_CONNECTED)
O_CSI = nr_get_csi_measurements(mac, frameP, slotP, &pucch);
// ACKNACK
O_ACK = get_downlink_ack(mac, frameP, slotP, &pucch);
NR_PUCCH_Config_t *pucch_Config = mac->current_UL_BWP.pucch_Config;
// if multiplexing of HARQ and CSI is not possible, transmit only HARQ bits
if ((O_ACK != 0) && (O_CSI != 0) &&
pucch_Config &&
pucch_Config->format2 &&
(pucch_Config->format2->choice.setup->simultaneousHARQ_ACK_CSI == NULL)) {
O_CSI = 0;
pucch.csi_part1_payload = 0;
pucch.csi_part2_payload = 0;
csi_res = nr_get_csi_measurements(mac, frameP, slotP, &pucch[num_res]);
if (csi_res > 0) {
num_res += csi_res;
}
N_UCI = O_SR + O_ACK + O_CSI;
mac->nr_ue_emul_l1.num_srs = O_SR;
mac->nr_ue_emul_l1.num_harqs = O_ACK;
mac->nr_ue_emul_l1.num_csi_reports = O_CSI;
// ACKNACK
bool any_harq = get_downlink_ack(mac, frameP, slotP, &pucch[num_res]);
if (any_harq)
num_res++;
if (num_res == 0)
return;
// do no transmit pucch if only SR scheduled and it is negative
if ((O_ACK + O_CSI) == 0 && pucch.sr_payload == 0)
if (num_res == 1 && pucch[0].n_sr > 0 && pucch[0].sr_payload == 0)
return;
if (N_UCI > 0) {
LOG_D(NR_MAC,"%d.%d configure pucch, O_SR %d, O_ACK %d, O_CSI %d\n",frameP,slotP,O_SR,O_ACK,O_CSI);
pucch.resource_set_id = find_pucch_resource_set(mac, O_ACK + O_CSI);
select_pucch_resource(mac, &pucch);
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
pthread_mutex_lock(&ul_config->mutex_ul_config);
AssertFatal(ul_config->number_pdus<FAPI_NR_UL_CONFIG_LIST_NUM, "ul_config->number_pdus %d out of bounds\n",ul_config->number_pdus);
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
nr_ue_configure_pucch(mac,
slotP,
rnti,
&pucch,
pucch_pdu,
O_SR, O_ACK, O_CSI);
nr_scheduled_response_t scheduled_response;
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, phy_data);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
if(mac->state == UE_WAIT_TX_ACK_MSG4)
mac->state = UE_CONNECTED;
if (num_res > 1)
multiplex_pucch_resource(mac, pucch, num_res);
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
pthread_mutex_lock(&ul_config->mutex_ul_config);
for (int j = 0; j < num_res; j++) {
if (pucch[j].n_harq + pucch[j].n_sr + pucch[j].n_csi != 0) {
LOG_D(NR_MAC,
"%d.%d configure pucch, O_ACK %d, O_SR %d, O_CSI %d\n",
frameP,
slotP,
pucch[j].n_harq,
pucch[j].n_sr,
pucch[j].n_csi);
mac->nr_ue_emul_l1.num_srs = pucch[j].n_sr;
mac->nr_ue_emul_l1.num_harqs = pucch[j].n_harq;
mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi;
AssertFatal(ul_config->number_pdus < FAPI_NR_UL_CONFIG_LIST_NUM,
"ul_config->number_pdus %d out of bounds\n",
ul_config->number_pdus);
fapi_nr_ul_config_pucch_pdu *pucch_pdu = &ul_config->ul_config_list[ul_config->number_pdus].pucch_config_pdu;
fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
mac->nr_ue_emul_l1.active_uci_sfn_slot = NFAPI_SFNSLOT2HEX(frameP, slotP);
pthread_mutex_unlock(&ul_config->mutex_ul_config);
nr_ue_configure_pucch(mac,
slotP,
mac->crnti, // FIXME not sure this is valid for all pucch instances
&pucch[j],
pucch_pdu);
nr_scheduled_response_t scheduled_response;
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, phy_data);
if (mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response);
if (mac->state == UE_WAIT_TX_ACK_MSG4)
mac->state = UE_CONNECTED;
}
}
}
void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) {
NR_UE_UL_BWP_t *current_UL_BWP = &mac->current_UL_BWP;
......
......@@ -968,9 +968,13 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
pucch_pdu->start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex;
pucch_pdu->data_scrambling_id = pusch_id!= NULL ? *pusch_id : *scc->physCellId;
pucch_pdu->dmrs_scrambling_id = id0!= NULL ? *id0 : *scc->physCellId;
pucch_pdu->prb_size = compute_pucch_prb_size(2,pucchres->format.choice.format2->nrofPRBs,
O_uci+O_sr,O_csi,pucch_Config->format2->choice.setup->maxCodeRate,
2,pucchres->format.choice.format2->nrofSymbols,8);
pucch_pdu->prb_size = compute_pucch_prb_size(2,
pucchres->format.choice.format2->nrofPRBs,
O_uci + O_sr,
pucch_Config->format2->choice.setup->maxCodeRate,
2,
pucchres->format.choice.format2->nrofSymbols,
8);
pucch_pdu->bit_len_csi_part1 = O_csi;
break;
case NR_PUCCH_Resource__format_PR_format3 :
......@@ -996,9 +1000,13 @@ void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu,
else
f3_dmrs_symbols = 2<<pucch_pdu->add_dmrs_flag;
}
pucch_pdu->prb_size = compute_pucch_prb_size(3,pucchres->format.choice.format3->nrofPRBs,
O_uci+O_sr,O_csi,pucch_Config->format3->choice.setup->maxCodeRate,
2-pucch_pdu->pi_2bpsk,pucchres->format.choice.format3->nrofSymbols-f3_dmrs_symbols,12);
pucch_pdu->prb_size = compute_pucch_prb_size(3,
pucchres->format.choice.format3->nrofPRBs,
O_uci + O_sr,
pucch_Config->format3->choice.setup->maxCodeRate,
2 - pucch_pdu->pi_2bpsk,
pucchres->format.choice.format3->nrofSymbols - f3_dmrs_symbols,
12);
pucch_pdu->bit_len_csi_part1 = O_csi;
break;
case NR_PUCCH_Resource__format_PR_format4 :
......
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