mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
9 Commits
4c6747951d
...
nr-qos-sch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8c8a0ba73 | ||
|
|
9f290096d3 | ||
|
|
9ca2e70c37 | ||
|
|
e58f319b67 | ||
|
|
95e1f356f8 | ||
|
|
6d9b8db232 | ||
|
|
28f5586f92 | ||
|
|
6f832f0a74 | ||
|
|
625cdcc176 |
@@ -311,7 +311,7 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
uint32_t A = rel15->TBSize[0]<<3;
|
||||
unsigned char *a=harq->pdu;
|
||||
if ( rel15->rnti != SI_RNTI)
|
||||
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
|
||||
trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], WS_C_RNTI, rel15->rnti, frame, slot,0, 0);
|
||||
|
||||
NR_gNB_SCH_STATS_t *stats=NULL;
|
||||
int first_free=-1;
|
||||
|
||||
@@ -172,7 +172,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
trace_NRpdu(DIRECTION_UPLINK,
|
||||
harq_process_ul_ue->a,
|
||||
harq_process_ul_ue->pusch_pdu.pusch_data.tb_size,
|
||||
0, WS_C_RNTI, rnti, frame, slot, 0, 0);
|
||||
WS_C_RNTI, rnti, frame, slot, 0, 0);
|
||||
|
||||
if (nr_ulsch_encoding(UE, ulsch_ue, frame_parms, harq_pid, G) == -1)
|
||||
return;
|
||||
|
||||
@@ -134,7 +134,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
|
||||
trace_NRpdu(DIRECTION_DOWNLINK,
|
||||
dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
|
||||
dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS / 8,
|
||||
pdu_type,
|
||||
WS_C_RNTI,
|
||||
dlsch0->rnti,
|
||||
proc->frame_rx,
|
||||
|
||||
@@ -271,9 +271,9 @@ int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLay
|
||||
void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
AssertFatal(UE_info->num_UEs == 1, "can have only a single UE\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[0];
|
||||
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0];
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
/* manually set free CCE to 0 */
|
||||
@@ -283,14 +283,14 @@ void nr_dlsim_preprocessor(module_id_t module_id,
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
sched_ctrl->coreset = get_coreset(module_id, scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->cce_index = 0;
|
||||
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
nr_set_pdsch_semi_static(NULL,
|
||||
scc,
|
||||
UE_info->CellGroup[0],
|
||||
UE_info->CellGroup,
|
||||
sched_ctrl->active_bwp,
|
||||
NULL,
|
||||
/* tda = */ 2,
|
||||
@@ -839,8 +839,7 @@ int main(int argc, char **argv)
|
||||
gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
|
||||
phy_init_nr_gNB(gNB,0,1);
|
||||
N_RB_DL = gNB->frame_parms.N_RB_DL;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
|
||||
UE_info->num_UEs=1;
|
||||
NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0];
|
||||
|
||||
// stub to configure frame_parms
|
||||
// nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions);
|
||||
@@ -1100,10 +1099,10 @@ int main(int argc, char **argv)
|
||||
|
||||
clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
|
||||
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1);
|
||||
UE_info->UE_sched_ctrl.harq_processes[harq_pid].ndi = !(trial&1);
|
||||
|
||||
|
||||
UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round;
|
||||
UE_info->UE_sched_ctrl.harq_processes[harq_pid].round = round;
|
||||
for (int i=0; i<MAX_NUM_CORESET; i++)
|
||||
gNB_mac->pdcch_cand[i] = 0;
|
||||
|
||||
|
||||
@@ -683,15 +683,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
"RNTI obtained through DU ID (%x) is different from CU ID (%x)\n",
|
||||
rnti, ctxt.rnti);
|
||||
int UE_out_of_sync = 0;
|
||||
|
||||
if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) {
|
||||
for (int n = 0; n < MAX_MOBILES_PER_GNB; ++n) {
|
||||
if (RC.nrmac[instance]->UE_info.active[n] == TRUE
|
||||
&& rnti == RC.nrmac[instance]->UE_info.rnti[n]) {
|
||||
UE_out_of_sync = 0;
|
||||
break;
|
||||
UEs_iterator(RC.nrmac[instance]->UE_info.list, UE) {
|
||||
if (UE->rnti == rnti) {
|
||||
UE_out_of_sync = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!UE)
|
||||
LOG_E(F1AP,"Not found rnti: %x\n", rnti);
|
||||
} else {
|
||||
for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
|
||||
if (RC.mac[instance]->UE_info.active[n] == TRUE
|
||||
@@ -701,7 +701,6 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't need the Cause */
|
||||
/* Optional RRC Container: if present, send to UE */
|
||||
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
|
||||
|
||||
@@ -2065,6 +2065,8 @@ void configure_gnb_du_mac(int inst) {
|
||||
NULL,
|
||||
0,
|
||||
0, // rnti
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -405,6 +405,8 @@ typedef struct {
|
||||
#define UL_SCH_LCID_L_BSR 0x3E
|
||||
#define UL_SCH_LCID_PADDING 0x3F
|
||||
|
||||
#define NR_MAX_PDU_SESSION 15
|
||||
#define NR_MAX_NUM_QFI 64
|
||||
#define NR_MAX_NUM_LCID 32
|
||||
#define NR_MAX_NUM_LCGID 8
|
||||
#define MAX_RLC_SDU_SUBHEADER_SIZE 3
|
||||
|
||||
@@ -54,9 +54,95 @@ extern RAN_CONTEXT_t RC;
|
||||
extern void mac_top_init_gNB(void);
|
||||
extern uint8_t nfapi_mode;
|
||||
|
||||
// Array containing the values of the 26 5QIs indexes
|
||||
const uint64_t fiveqi_idx[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5, 6, 7, 8, 9, 69, 70, 79, 80, 82, 83, 84, 85, 86};
|
||||
|
||||
// 3GPP TS 23.501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
|
||||
// resource type, default priority level
|
||||
// 0 = GBR, 1 = Non-GBR, 2 = delay critical GBR
|
||||
const uint64_t table_5_6_4_1[27][2] = {
|
||||
{0,20},
|
||||
{0,40},
|
||||
{0,30},
|
||||
{0,50},
|
||||
{0,7},
|
||||
{0,20},
|
||||
{0,15},
|
||||
{0,56},
|
||||
{0,56},
|
||||
{0,56},
|
||||
{0,56},
|
||||
{1,10},
|
||||
{1,60},
|
||||
{1,70},
|
||||
{1,80},
|
||||
{1,90},
|
||||
{1,5},
|
||||
{1,55},
|
||||
{1,65},
|
||||
{1,68},
|
||||
{2,19},
|
||||
{2,22},
|
||||
{2,24},
|
||||
{2,21},
|
||||
{2,18}
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a QoS comparator function for qsort.
|
||||
*
|
||||
* @lcid1 pointer to the first array element
|
||||
* @lcid1 pointer to the second array element
|
||||
* @return negative return value means that *p1 goes before *p2
|
||||
* zero return value means that that *p1 is equivalent to *p2
|
||||
* positive return value means that *p1 goes after *p2
|
||||
*
|
||||
* The function fetches the indexes i and j by matching the 26 5QIs values with the 5QI in the DRB to be configured.
|
||||
* The indexes are used to fetch the Priority Level from table_5_6_4_1.
|
||||
* Lower Priority Level means higher priority.
|
||||
* The sorting of the array is based on the Priority Levels. SRBs are placed at the top of the array, followed by DRBs by descending priority order.
|
||||
*
|
||||
**/
|
||||
static int QoS_comp(const void *lcid1, const void *lcid2, void *sctrl) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = (NR_UE_sched_ctrl_t*)sctrl;
|
||||
uint8_t lcid_1 = *(uint8_t *)lcid1;
|
||||
uint8_t lcid_2 = *(uint8_t *)lcid2;
|
||||
if (lcid_1 >= 4 && lcid_2 >= 4) {
|
||||
uint8_t i, j;
|
||||
uint64_t fiveQI_1 = sched_ctrl->nr_QoS_config[lcid_1 - 4].fiveQI;
|
||||
uint64_t fiveQI_2 = sched_ctrl->nr_QoS_config[lcid_2 - 4].fiveQI;
|
||||
for (i = 0; i < 26; i++) {
|
||||
if (fiveqi_idx[i] == fiveQI_1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < 26; j++) {
|
||||
if (fiveqi_idx[j] == fiveQI_2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
LOG_I(NR_MAC, "LCID %d (DRB %d) with 5QI %ld and priority level %ld \n", lcid_1, lcid_1 - 3, fiveQI_1, table_5_6_4_1[i][1]);
|
||||
LOG_I(NR_MAC, "LCID %d (DRB %d) with 5QI %ld and priority level %ld \n", lcid_2, lcid_2 - 3, fiveQI_2, table_5_6_4_1[j][1]);
|
||||
if (table_5_6_4_1[i][1] > table_5_6_4_1[j][1]) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (lcid_1 < 4 && lcid_2 < 4) {
|
||||
return 0;
|
||||
} else if (lcid_1 < 4) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list,
|
||||
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_bearer2release_list,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
NR_DRB_ToAddModList_t *DRB_configList) {
|
||||
|
||||
if (rlc_bearer2release_list) {
|
||||
for (int i = 0; i < rlc_bearer2release_list->list.count; i++) {
|
||||
@@ -86,17 +172,65 @@ void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *
|
||||
if (!found) {
|
||||
sched_ctrl->dl_lc_num++;
|
||||
sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
|
||||
LOG_D(NR_MAC, "Adding LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid);
|
||||
LOG_D(NR_MAC, "Adding LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid < 4 ? lcid : lcid - 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "In %s: total num of active bearers %d) \n",
|
||||
__FUNCTION__,
|
||||
sched_ctrl->dl_lc_num);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fills the QoS config at the MAC layer and performs the sorting of the LCIDs based on the QoS Priority Levels
|
||||
*
|
||||
* @sched_ctrl pointer to sched_ctrl, eventually used by the scheduler
|
||||
* @DRB_configList pointer to the list of DRB IDs to be configured, contains the SDAP configuration IE
|
||||
* @pduSession pointer to pduSession containing the QoS configuration (5QI, QFI)
|
||||
*
|
||||
* This function fetches the QoS configuration from the PDU Session and matches the QFI with the DRB IDs.
|
||||
* The information is therefore stored in the nr_QoS_config struct and eventually used for scheduling.
|
||||
**/
|
||||
void process_QoSConfig(NR_UE_sched_ctrl_t *sched_ctrl, NR_DRB_ToAddModList_t *DRB_configList, pdu_session_param_t *pduSession) {
|
||||
|
||||
if (DRB_configList) {
|
||||
LOG_D(NR_MAC, "In %s: number of DRBs in DRB_configList: %d \n", __func__, DRB_configList->list.count);
|
||||
for (int i = 0; i < DRB_configList->list.count; i++){
|
||||
NR_SDAP_Config_t *sdap_config = DRB_configList->list.array[i]->cnAssociation->choice.sdap_Config;
|
||||
uint8_t nb_QoS_flows = sdap_config->mappedQoS_FlowsToAdd->list.count;
|
||||
long drb_id = DRB_configList->list.array[i]->drb_Identity;
|
||||
long pdu_Session_id = sdap_config->pdu_Session;
|
||||
LOG_D(NR_MAC, "Processing QoS configuration for PDU Session ID %ld, DRB %ld \n", pdu_Session_id, drb_id);
|
||||
LOG_D(NR_MAC, "In %s: number of QoS in mappedQoS_FlowsToAdd: %d \n", __func__, nb_QoS_flows);
|
||||
for (int q = 0; q < nb_QoS_flows; q++) {
|
||||
if (pduSession) {
|
||||
for (int p = 0; p < NR_MAX_PDU_SESSION; p++){
|
||||
if (pduSession[p].status == PDU_SESSION_STATUS_ESTABLISHED || pduSession[p].status == PDU_SESSION_STATUS_DONE) {
|
||||
uint8_t qfi = pduSession[p].param.qos[q].qfi;
|
||||
if (qfi == *DRB_configList->list.array[i]->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.array[q]) {
|
||||
sched_ctrl->nr_QoS_config[drb_id - 1].fiveQI = pduSession[p].param.qos[q].fiveQI;
|
||||
LOG_D(NR_MAC, "In %s: pdu_Session ID %ld drb_id %ld: 5QI %lu QFI %d \n",
|
||||
__func__,
|
||||
pdu_Session_id,
|
||||
drb_id,
|
||||
sched_ctrl->nr_QoS_config[drb_id - 1].fiveQI,
|
||||
qfi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qsort_r((void *)sched_ctrl->dl_lc_ids, sizeof(uint8_t) * sched_ctrl->dl_lc_num, sizeof(uint8_t), QoS_comp, (void *)sched_ctrl);
|
||||
|
||||
LOG_D(NR_MAC, "In %s: total num of active bearers %d \n", __func__, sched_ctrl->dl_lc_num);
|
||||
LOG_D(NR_MAC, "Dumping sched_ctrl->dl_lc_ids sorted by Priority Level:\n");
|
||||
for (int j = 0; j < sched_ctrl->dl_lc_num; j++) {
|
||||
int lcid = sched_ctrl->dl_lc_ids[j];
|
||||
LOG_D(NR_MAC, "LCID %d (%s %d)\n", lcid, lcid < 4 ? "SRB" : "DRB", lcid < 4 ? lcid : lcid - 3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void process_drx_Config(NR_UE_sched_ctrl_t *sched_ctrl,NR_SetupRelease_DRX_Config_t *drx_Config) {
|
||||
if (!drx_Config) return;
|
||||
@@ -138,7 +272,7 @@ void process_phr_Config(NR_UE_sched_ctrl_t *sched_ctrl,NR_SetupRelease_PHR_Confi
|
||||
}
|
||||
}
|
||||
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl) {
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl, pdu_session_param_t *pduSession, NR_DRB_ToAddModList_t *DRB_configList) {
|
||||
|
||||
AssertFatal(CellGroup, "CellGroup is null\n");
|
||||
NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = CellGroup->mac_CellGroupConfig;
|
||||
@@ -156,7 +290,8 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sche
|
||||
|
||||
}
|
||||
|
||||
process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList,CellGroup->rlc_BearerToReleaseList,sched_ctrl);
|
||||
process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList,CellGroup->rlc_BearerToReleaseList,sched_ctrl, DRB_configList);
|
||||
process_QoSConfig(sched_ctrl, DRB_configList, pduSession);
|
||||
|
||||
}
|
||||
|
||||
@@ -456,18 +591,17 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S
|
||||
if (rrc_reconfiguration_delay == 0) {
|
||||
return -1;
|
||||
}
|
||||
const int UE_id = find_nr_UE_id(Mod_idP,rnti);
|
||||
if (UE_id < 0) {
|
||||
|
||||
NR_UE_info_t *UE_info = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti);
|
||||
if (!UE_info) {
|
||||
LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
const uint16_t sf_ahead = 6/(0x01<<subcarrierSpacing) + ((6%(0x01<<subcarrierSpacing))>0);
|
||||
const uint16_t sl_ahead = sf_ahead * (0x01<<subcarrierSpacing);
|
||||
sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<<subcarrierSpacing) + sl_ahead;
|
||||
LOG_I(NR_MAC, "Activating RRC processing timer for UE %d\n", UE_id);
|
||||
LOG_I(NR_MAC, "Activating RRC processing timer for UE %04x\n", UE_info->rnti);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -483,7 +617,9 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
NR_BCCH_DL_SCH_Message_t *sib1,
|
||||
int add_ue,
|
||||
uint32_t rnti,
|
||||
NR_CellGroupConfig_t *CellGroup) {
|
||||
NR_CellGroupConfig_t *CellGroup,
|
||||
pdu_session_param_t *pduSession,
|
||||
NR_DRB_ToAddModList_t *DRB_configList) {
|
||||
|
||||
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);
|
||||
@@ -616,11 +752,15 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
if (add_ue == 1 && get_softmodem_params()->phy_test) {
|
||||
const int UE_id = add_new_nr_ue(Mod_idP, rnti, CellGroup);
|
||||
LOG_I(NR_MAC,"Added new UE_id %d/%x with initial CellGroup\n",UE_id,rnti);
|
||||
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
|
||||
NR_UE_info_t* UE = add_new_nr_ue(RC.nrmac[Mod_idP], rnti, CellGroup);
|
||||
if (UE)
|
||||
LOG_I(NR_MAC,"Added new UE %x with initial CellGroup\n", rnti);
|
||||
else {
|
||||
LOG_E(NR_MAC,"Error adding UE %04x\n", rnti);
|
||||
return -1;
|
||||
}
|
||||
process_CellGroup(CellGroup, &UE->UE_sched_ctrl, pduSession, DRB_configList);
|
||||
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
|
||||
const int CC_id = 0;
|
||||
NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id];
|
||||
@@ -667,12 +807,16 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
LOG_I(NR_MAC,"Added new RA process for UE RNTI %04x with initial CellGroup\n", rnti);
|
||||
} else { // CellGroup has been updated
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon;
|
||||
const int UE_id = find_nr_UE_id(Mod_idP,rnti);
|
||||
NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC, "Can't find UE %04x\n", rnti);
|
||||
return -1;
|
||||
}
|
||||
int target_ss;
|
||||
UE_info->CellGroup[UE_id] = CellGroup;
|
||||
LOG_I(NR_MAC,"Modified UE_id %d/%x with CellGroup\n",UE_id,rnti);
|
||||
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
UE->CellGroup = CellGroup;
|
||||
LOG_I(NR_MAC,"Modified rnti %04x with CellGroup\n",rnti);
|
||||
process_CellGroup(CellGroup,&UE->UE_sched_ctrl, pduSession, DRB_configList);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
||||
if (get_softmodem_params()->sa) {
|
||||
// add all available DL HARQ processes for this UE in SA
|
||||
@@ -695,7 +839,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
}
|
||||
sched_ctrl->search_space = get_searchspace(sib1 ? sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL, scc, bwpd, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(Mod_idP, scc, bwpd, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->coreset = get_coreset(RC.nrmac[Mod_idP], scc, bwpd, sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[Mod_idP],
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
@@ -708,7 +852,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup
|
||||
)
|
||||
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, Mod_idP);
|
||||
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
|
||||
}
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
|
||||
|
||||
@@ -104,167 +104,6 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
TX_req[CC_idP].Number_of_PDUs = 0;
|
||||
|
||||
}
|
||||
/*
|
||||
void check_nr_ul_failure(module_id_t module_idP,
|
||||
int CC_id,
|
||||
int UE_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
nfapi_nr_dl_dci_request_t *DL_req = &RC.nrmac[module_idP]->DL_req[0];
|
||||
uint16_t rnti = UE_RNTI(module_idP, UE_id);
|
||||
NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
|
||||
|
||||
// check uplink failure
|
||||
if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
|
||||
(UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
|
||||
LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
|
||||
if (UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
|
||||
UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
|
||||
|
||||
// add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
|
||||
nfapi_nr_dl_dci_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_tti_request_body.dl_config_pdu_list[DL_req[CC_id].dl_tti_request_body.number_pdu];
|
||||
memset((void *) dl_config_pdu, 0,sizeof(nfapi_dl_dci_request_pdu_t));
|
||||
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
|
||||
dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_DCI_REQUEST_DCI_DL_PDU_REL8_TAG;
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id),
|
||||
UE_info->UE_sched_ctrl[UE_id].
|
||||
dl_cqi[CC_id], format1A);
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
|
||||
|
||||
AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >= 0) && (cc[CC_id].mib->message.dl_Bandwidth < 6),
|
||||
"illegal dl_Bandwidth %d\n",
|
||||
(int) cc[CC_id].mib->message.dl_Bandwidth);
|
||||
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = nr_pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth];
|
||||
DL_req[CC_id].dl_tti_request_body.number_dci++;
|
||||
DL_req[CC_id].dl_tti_request_body.number_pdu++;
|
||||
DL_req[CC_id].dl_tti_request_body.tl.tag = NFAPI_DL_TTI_REQUEST_BODY_TAG;
|
||||
LOG_I(MAC,
|
||||
"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
|
||||
UE_id, rnti,
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer,
|
||||
dl_config_pdu->dci_dl_pdu.
|
||||
dci_dl_pdu_rel8.resource_block_coding);
|
||||
} else { // ra_pdcch_sent==1
|
||||
LOG_I(MAC,
|
||||
"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
|
||||
UE_id, rnti,
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer);
|
||||
if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames
|
||||
}
|
||||
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer++;
|
||||
// check threshold
|
||||
if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
|
||||
// inform RRC of failure and clear timer
|
||||
LOG_I(MAC,
|
||||
"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
|
||||
UE_id, rnti);
|
||||
mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti);
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync = 1;
|
||||
|
||||
//Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
|
||||
if (rrc_agent_registered[module_idP]) {
|
||||
LOG_W(MAC, "notify flexran Agent of UE state change\n");
|
||||
agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
|
||||
rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
|
||||
}
|
||||
}
|
||||
} // ul_failure_timer>0
|
||||
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
|
||||
{
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
nfapi_ul_config_request_body_t *ul_req;
|
||||
int CC_id, UE_id;
|
||||
NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels;
|
||||
SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon;
|
||||
struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated;
|
||||
uint8_t TSFC;
|
||||
uint16_t deltaTSFC; // bitmap
|
||||
uint8_t srs_SubframeConfig;
|
||||
|
||||
// table for TSFC (Period) and deltaSFC (offset)
|
||||
const uint16_t deltaTSFCTabType1[15][2] = { {1, 1}, {1, 2}, {2, 2}, {1, 5}, {2, 5}, {4, 5}, {8, 5}, {3, 5}, {12, 5}, {1, 10}, {2, 10}, {4, 10}, {8, 10}, {351, 10}, {383, 10} }; // Table 5.5.3.3-2 3GPP 36.211 FDD
|
||||
const uint16_t deltaTSFCTabType2[14][2] = { {2, 5}, {6, 5}, {10, 5}, {18, 5}, {14, 5}, {22, 5}, {26, 5}, {30, 5}, {70, 10}, {74, 10}, {194, 10}, {326, 10}, {586, 10}, {210, 10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD
|
||||
|
||||
uint16_t srsPeriodicity, srsOffset;
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon;
|
||||
// check if SRS is enabled in this frame/subframe
|
||||
if (soundingRS_UL_ConfigCommon) {
|
||||
srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig;
|
||||
if (cc[CC_id].tdd_Config == NULL) { // FDD
|
||||
deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
|
||||
TSFC = deltaTSFCTabType1[srs_SubframeConfig][1];
|
||||
} else { // TDD
|
||||
deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
|
||||
TSFC = deltaTSFCTabType2[srs_SubframeConfig][1];
|
||||
}
|
||||
// Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
|
||||
uint16_t tmp = (subframeP % TSFC);
|
||||
|
||||
if ((1 << tmp) & deltaTSFC) {
|
||||
// This is an SRS subframe, loop over UEs
|
||||
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
|
||||
if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue;
|
||||
ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body;
|
||||
// drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
|
||||
if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue;
|
||||
|
||||
AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
|
||||
"physicalConfigDedicated is null for UE %d\n",
|
||||
UE_id);
|
||||
|
||||
if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) {
|
||||
if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
|
||||
get_srs_pos(&cc[CC_id],
|
||||
soundingRS_UL_ConfigDedicated->choice.
|
||||
setup.srs_ConfigIndex,
|
||||
&srsPeriodicity, &srsOffset);
|
||||
if (((10 * frameP + subframeP) % srsPeriodicity) == srsOffset) {
|
||||
// Program SRS
|
||||
ul_req->srs_present = 1;
|
||||
nfapi_ul_config_request_pdu_t * ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus];
|
||||
memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
|
||||
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_SRS_PDU_TYPE;
|
||||
ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu));
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_info->UE_template[CC_id][UE_id].rnti;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;
|
||||
ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; // ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port = ;//
|
||||
// ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs = ;//
|
||||
RC.nrmac[module_idP]->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP;
|
||||
RC.nrmac[module_idP]->UL_req[CC_id].header.message_id = NFAPI_UL_CONFIG_REQUEST;
|
||||
ul_req->number_of_pdus++;
|
||||
} // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset)
|
||||
} // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup)
|
||||
} // if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL)
|
||||
} // for (UE_id ...
|
||||
} // if((1<<tmp) & deltaTSFC)
|
||||
|
||||
} // SRS config
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
if (slot>=64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed)
|
||||
@@ -370,7 +209,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
schedule_nr_prach(module_idP, f, s);
|
||||
}
|
||||
|
||||
|
||||
// Schedule CSI-RS transmission
|
||||
nr_csirs_scheduling(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing]);
|
||||
|
||||
@@ -396,10 +234,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
nr_schedule_ue_spec(module_idP, frame, slot);
|
||||
stop_meas(&gNB->schedule_dlsch);
|
||||
|
||||
nr_schedule_pucch(module_idP, frame, slot);
|
||||
nr_schedule_pucch(RC.nrmac[module_idP], frame, slot);
|
||||
|
||||
// This schedule SR after PUCCH for multiplexing
|
||||
nr_sr_reporting(module_idP, frame, slot);
|
||||
nr_sr_reporting(RC.nrmac[module_idP], frame, slot);
|
||||
|
||||
stop_meas(&RC.nrmac[module_idP]->eNB_scheduler);
|
||||
|
||||
|
||||
@@ -542,8 +542,10 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &cc->ra[i];
|
||||
pr_found = 0;
|
||||
const int UE_id = find_nr_UE_id(module_idP, ra->rnti);
|
||||
if (UE_id != -1) {
|
||||
const NR_UE_info_t * UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
|
||||
if (UE) {
|
||||
// the UE is already registered
|
||||
LOG_I(NR_MAC, "Received RA for existing RNTI %04x\n", ra->rnti);
|
||||
continue;
|
||||
}
|
||||
if (ra->state == RA_IDLE) {
|
||||
@@ -631,7 +633,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
|
||||
AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n");
|
||||
|
||||
ra->coreset = get_coreset(module_idP, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
ra->coreset = get_coreset(nr_mac, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common);
|
||||
ra->sched_pdcch = set_pdcch_structure(nr_mac,
|
||||
ra->ra_ss,
|
||||
ra->coreset,
|
||||
@@ -661,12 +663,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
|
||||
|
||||
int loop = 0;
|
||||
LOG_W(NR_MAC,"in init, generate new rnti, rnti: %04x\n", ra->rnti);
|
||||
if (ra->rnti == 0) { // This condition allows for the usage of a preconfigured rnti for the CFRA
|
||||
do {
|
||||
ra->rnti = (taus() % 65518) + 1;
|
||||
loop++;
|
||||
} while (loop != 100
|
||||
&& !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
|
||||
&& !((find_nr_UE(&nr_mac->UE_info, ra->rnti) == NULL) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
|
||||
&& ra->rnti >= 1 && ra->rnti <= 65519));
|
||||
if (loop == 100) {
|
||||
LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
@@ -679,7 +682,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
ra->beam_id = beam_index;
|
||||
|
||||
LOG_I(NR_MAC,
|
||||
"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
|
||||
"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB, new rnti %04x "
|
||||
"index %u RA index %d\n",
|
||||
module_idP,
|
||||
CC_id,
|
||||
@@ -687,6 +690,7 @@ void nr_initiate_ra_proc(module_id_t module_idP,
|
||||
ra->Msg2_frame,
|
||||
ra->Msg2_slot,
|
||||
ra->RA_rnti,
|
||||
ra->rnti,
|
||||
cc->ssb_index[beam_index],
|
||||
i);
|
||||
|
||||
@@ -1521,7 +1525,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
}
|
||||
|
||||
ra->state = WAIT_Msg3;
|
||||
LOG_D(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
|
||||
LOG_W(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: rnti %04x RA state %d\n", module_idP, frameP, slotP, ra->rnti, ra->state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1564,9 +1568,14 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
ra->rnti = ra->crnti;
|
||||
}
|
||||
|
||||
int UE_id = find_nr_UE_id(module_idP, ra->rnti);
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_info_t * UE = find_nr_UE(&nr_mac->UE_info, ra->rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC,"want to generate Msg4, but rnti %04x not in the table\n", ra->rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
NR_BWP_t *genericParameters = bwp ? & bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
|
||||
@@ -1599,7 +1608,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
// Remove UE associated to TC-RNTI
|
||||
if(harq->round==0 && ra->msg3_dcch_dtch) {
|
||||
mac_remove_nr_ue(module_idP, tc_rnti);
|
||||
mac_remove_nr_ue(nr_mac, tc_rnti);
|
||||
}
|
||||
|
||||
// get CCEindex, needed also for PUCCH and then later for PDCCH
|
||||
@@ -1630,7 +1639,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI);
|
||||
|
||||
int alloc = nr_acknack_scheduling(module_idP, UE_id, frameP, slotP, r_pucch, 1);
|
||||
int alloc = nr_acknack_scheduling(module_idP, UE, frameP, slotP, r_pucch, 1);
|
||||
AssertFatal(alloc>=0,"Couldn't find a pucch allocation for ack nack (msg4)\n");
|
||||
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[alloc];
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
@@ -1930,10 +1939,9 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
if(ra->msg3_dcch_dtch) {
|
||||
// If the UE used MSG3 to transfer a DCCH or DTCH message, then contention resolution is successful upon transmission of PDCCH
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CBRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
LOG_I(NR_MAC, "(ue rnti 0x%04x) CBRA procedure succeeded!\n", ra->rnti);
|
||||
nr_clear_ra_proc(module_idP, CC_id, frameP, ra);
|
||||
UE_info->active[UE_id] = true;
|
||||
UE_info->Msg4_ACKed[UE_id] = true;
|
||||
UE->Msg4_ACKed = true;
|
||||
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
harq->feedback_slot = -1;
|
||||
@@ -1950,23 +1958,20 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
|
||||
|
||||
void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
|
||||
|
||||
int UE_id = find_nr_UE_id(module_id, ra->rnti);
|
||||
NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, ra->rnti);
|
||||
const int current_harq_pid = ra->harq_pid;
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
|
||||
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
|
||||
LOG_D(NR_MAC, "ue %d, rnti 0x%04x, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
|
||||
LOG_D(NR_MAC, "ue rnti 0x%04x, harq is waiting %d, round %d, frame %d %d, harq id %d\n", ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
|
||||
|
||||
if (harq->is_waiting == 0) {
|
||||
if (harq->round == 0) {
|
||||
if (stats->dlsch_errors == 0) {
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
UE_info->active[UE_id] = true;
|
||||
UE_info->Msg4_ACKed[UE_id] = true;
|
||||
|
||||
LOG_A(NR_MAC, "(ue rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", ra->rnti);
|
||||
UE->Msg4_ACKed = true;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
@@ -1975,7 +1980,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
|
||||
sched_ctrl->rrc_processing_timer = (NR_RRC_SETUP_DELAY_MS << genericParameters->subcarrierSpacing); // RRCSetup 10 ms
|
||||
}
|
||||
else {
|
||||
LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) RA Procedure failed at Msg4!\n", UE_id, ra->rnti);
|
||||
LOG_I(NR_MAC, "(ue rnti 0x%04x) RA Procedure failed at Msg4!\n", ra->rnti);
|
||||
}
|
||||
|
||||
nr_clear_ra_proc(module_id, CC_id, frame, ra);
|
||||
@@ -1984,7 +1989,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG_D(NR_MAC, "(ue %i, rnti 0x%04x) Received Nack of RA-Msg4. Preparing retransmission!\n", UE_id, ra->rnti);
|
||||
LOG_I(NR_MAC, "(ue rnti 0x%04x) Received Nack of RA-Msg4. Preparing retransmission!\n", ra->rnti);
|
||||
ra->Msg4_frame = (frame + 1) % 1024;
|
||||
ra->Msg4_slot = 1;
|
||||
ra->state = Msg4;
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
#define WORD 32
|
||||
//#define SIZE_OF_POINTER sizeof (void *)
|
||||
|
||||
extern const uint64_t fiveqi_idx[26];
|
||||
extern const uint64_t table_5_6_4_1[27][2];
|
||||
|
||||
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp) {
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
const int bwp_id = bwp ? bwp->bwp_Id : 0;
|
||||
@@ -92,7 +95,7 @@ void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *
|
||||
bwp ? bwp->bwp_Dedicated : NULL,
|
||||
target_ss);
|
||||
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(module_id, scc, bwp ? bwp->bwp_Dedicated : NULL, search_space, target_ss);
|
||||
NR_ControlResourceSet_t *coreset = get_coreset(nrmac, scc, bwp ? bwp->bwp_Dedicated : NULL, search_space, target_ss);
|
||||
// get coreset symbol "map"
|
||||
const uint16_t symb_coreset = (1 << coreset->duration) - 1;
|
||||
|
||||
@@ -399,7 +402,7 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
|
||||
#define BLER_UPDATE_FRAME 10
|
||||
#define BLER_FILTER 0.9f
|
||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table) {
|
||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, NR_UE_info_t* UE, int mcs_table) {
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
@@ -409,7 +412,7 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
if (nrmac->dl_max_mcs>max_allowed_mcs)
|
||||
max_mcs = max_allowed_mcs;
|
||||
|
||||
NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
|
||||
NR_DL_bler_stats_t *bler_stats = &UE->UE_sched_ctrl.dl_bler_stats;
|
||||
|
||||
/* first call: everything is zero. Initialize to sensible default */
|
||||
if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
|
||||
@@ -426,7 +429,7 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
diff += 1024 * n;
|
||||
|
||||
const uint8_t old_mcs = bler_stats->mcs;
|
||||
const NR_mac_stats_t *stats = &nrmac->UE_info.mac_stats[UE_id];
|
||||
const NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
|
||||
// TODO put back this condition when relevant
|
||||
/*const int dret3x = stats->dlsch_rounds[3] - bler_stats->dlsch_rounds[3];
|
||||
@@ -475,10 +478,9 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
UEs_iterator(RC.nrmac[module_id]->UE_info.list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->num_total_bytes = 0;
|
||||
sched_ctrl->dl_pdus_total = 0;
|
||||
|
||||
@@ -486,13 +488,11 @@ void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
|
||||
for (int i = 0; i < sched_ctrl->dl_lc_num; ++i) {
|
||||
const int lcid = sched_ctrl->dl_lc_ids[i];
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
LOG_D(NR_MAC, "In %s: UE %d/%x: LCID %d\n", __FUNCTION__, UE_id, rnti, lcid);
|
||||
|
||||
const uint16_t rnti = UE->rnti;
|
||||
LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid);
|
||||
if (lcid == DL_SCH_LCID_DTCH && sched_ctrl->rrc_processing_timer > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
start_meas(&RC.nrmac[module_id]->rlc_status_ind);
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
rnti,
|
||||
@@ -518,7 +518,7 @@ void nr_store_dlsch_buffer(module_id_t module_id,
|
||||
slot,
|
||||
lcid < 4 ? "DCCH":"DTCH",
|
||||
lcid,
|
||||
UE_id,
|
||||
UE->rnti,
|
||||
sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||
sched_ctrl->num_total_bytes,
|
||||
sched_ctrl->dl_pdus_total,
|
||||
@@ -532,16 +532,15 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
sub_frame_t slot,
|
||||
uint16_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
int UE_id,
|
||||
NR_UE_info_t * UE,
|
||||
int current_harq_pid) {
|
||||
|
||||
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
@@ -581,7 +580,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
rbStart++;
|
||||
|
||||
if (rbStart >= bwpSize) {
|
||||
LOG_D(NR_MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
|
||||
LOG_D(NR_MAC, "cannot allocate retransmission for RNTI %04x: no resources\n", UE->rnti);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -654,7 +653,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
|
||||
uint8_t nr_of_candidates;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
@@ -676,8 +675,8 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n",
|
||||
frame, slot, UE_id, UE_info->rnti[UE_id]);
|
||||
LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission RNTI %04x\n",
|
||||
frame, slot, UE->rnti);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -685,12 +684,11 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0);
|
||||
if (alloc<0) {
|
||||
LOG_D(MAC,
|
||||
"could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
UE_id,
|
||||
UE_info->rnti[UE_id],
|
||||
"could not find PUCCH for UE %04x@%d.%d\n",
|
||||
UE->rnti,
|
||||
frame,
|
||||
slot);
|
||||
RC.nrmac[module_id]->pdcch_cand[cid]--;
|
||||
@@ -716,30 +714,36 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
float thr_ue[MAX_MOBILES_PER_GNB];
|
||||
uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
|
||||
typedef struct UEsched_s {
|
||||
float coef;
|
||||
NR_UE_info_t * UE;
|
||||
} UEsched_t;
|
||||
|
||||
static int comparator(const void *p, const void *q) {
|
||||
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
|
||||
}
|
||||
|
||||
void pf_dl(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
NR_list_t *UE_list,
|
||||
NR_UE_info_t **UE_list,
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint16_t *rballoc_mask) {
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
NR_UE_info_t *UE_info = &mac->UE_info;
|
||||
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
||||
float coeff_ue[MAX_MOBILES_PER_GNB];
|
||||
// UEs that could be scheduled
|
||||
int ue_array[MAX_MOBILES_PER_GNB];
|
||||
int layers[MAX_MOBILES_PER_GNB];
|
||||
NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB };
|
||||
|
||||
UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
|
||||
int remainUEs=max_num_ue;
|
||||
int curUE=0;
|
||||
|
||||
/* Loop UE_info->list to check retransmission */
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
if (UE_info->Msg4_ACKed[UE_id] != true) continue;
|
||||
UEs_iterator(UE_list, UE) {
|
||||
if (UE->Msg4_ACKed != true)
|
||||
continue;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
||||
|
||||
@@ -747,17 +751,17 @@ void pf_dl(module_id_t module_id,
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
layers[UE_id] = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
|
||||
UE->layers = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
|
||||
/* Calculate Throughput */
|
||||
const float a = 0.0005f; // corresponds to 200ms window
|
||||
const uint32_t b = UE_info->mac_stats[UE_id].dlsch_current_bytes;
|
||||
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
|
||||
const uint32_t b = UE->mac_stats.dlsch_current_bytes;
|
||||
UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b;
|
||||
|
||||
/* retransmission */
|
||||
if (sched_pdsch->dl_harq_pid >= 0) {
|
||||
/* Allocate retransmission */
|
||||
bool r = allocate_dl_retransmission(
|
||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
|
||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pdsch->dl_harq_pid);
|
||||
|
||||
if (!r) {
|
||||
LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
|
||||
@@ -765,9 +769,12 @@ void pf_dl(module_id_t module_id,
|
||||
}
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
remainUEs--;
|
||||
|
||||
if (max_num_ue < 0) return;
|
||||
if (remainUEs == 0)
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
return;
|
||||
} else {
|
||||
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
|
||||
if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024)
|
||||
@@ -775,8 +782,8 @@ void pf_dl(module_id_t module_id,
|
||||
|
||||
/* Calculate coeff */
|
||||
set_dl_mcs(sched_pdsch,sched_ctrl,&mac->dl_max_mcs,ps->mcsTableIdx);
|
||||
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE_id, ps->mcsTableIdx);
|
||||
layers[UE_id] = set_dl_nrOfLayers(sched_ctrl);
|
||||
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE, ps->mcsTableIdx);
|
||||
UE->layers = set_dl_nrOfLayers(sched_ctrl);
|
||||
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
uint32_t tbs = nr_compute_tbs(Qm,
|
||||
@@ -786,40 +793,26 @@ void pf_dl(module_id_t module_id,
|
||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
layers[UE_id]) >> 3;
|
||||
coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
|
||||
LOG_D(NR_MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
|
||||
b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
|
||||
UE->layers) >> 3;
|
||||
float coeff_ue = (float) tbs / UE->dl_thr_ue;
|
||||
LOG_D(NR_MAC,"UE %04x b %d, thr_ue %f, tbs %d, coeff_ue %f\n",
|
||||
UE->rnti, b, UE->dl_thr_ue, tbs, UE->dl_coeff_ue);
|
||||
/* Create UE_sched list for UEs eligible for new transmission*/
|
||||
add_tail_nr_list(&UE_sched, UE_id);
|
||||
UE_sched[curUE].coef=coeff_ue;
|
||||
UE_sched[curUE].UE=UE;
|
||||
curUE++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
|
||||
UEsched_t *iterator=UE_sched;
|
||||
|
||||
const int min_rbSize = 5;
|
||||
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (max_num_ue > 0 && n_rb_sched >= min_rbSize && UE_sched.head >= 0) {
|
||||
/* Find max coeff from UE_sched*/
|
||||
int *max = &UE_sched.head; /* assume head is max */
|
||||
int *p = &UE_sched.next[*max];
|
||||
|
||||
while (*p >= 0) {
|
||||
/* if the current one has larger coeff, save for later */
|
||||
if (coeff_ue[*p] > coeff_ue[*max])
|
||||
max = p;
|
||||
|
||||
p = &UE_sched.next[*p];
|
||||
}
|
||||
|
||||
/* remove the max one: do not use remove_nr_list() it goes through the
|
||||
* whole list every time. Note that UE_sched.tail might not be set
|
||||
* correctly anymore */
|
||||
const int UE_id = *max;
|
||||
p = &UE_sched.next[*max];
|
||||
*max = UE_sched.next[*max];
|
||||
*p = -1;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) {
|
||||
|
||||
NR_CellGroupConfig_t *cg = iterator->UE->CellGroup;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
@@ -834,26 +827,32 @@ void pf_dl(module_id_t module_id,
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
|
||||
const uint16_t rnti = iterator->UE->rnti;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ?
|
||||
RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 :
|
||||
NULL;
|
||||
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
sib1);
|
||||
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ?
|
||||
sched_ctrl->coreset->controlResourceSetId :
|
||||
RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
const uint16_t bwpSize = coresetid == 0 ?
|
||||
RC.nrmac[module_id]->cset0_bwp_size :
|
||||
NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
if (sched_ctrl->available_dl_harq.head < 0) {
|
||||
LOG_D(MAC, "UE %d RNTI %04x has no free HARQ process, skipping\n", UE_id, UE_info->rnti[UE_id]);
|
||||
LOG_D(MAC, "RNTI %04x has no free HARQ process, skipping\n", iterator->UE->rnti);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti);
|
||||
uint8_t nr_of_candidates;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
@@ -875,7 +874,7 @@ void pf_dl(module_id_t module_id,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
|
||||
LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI RNTI %04x\n", frame, slot, rnti);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -883,12 +882,11 @@ void pf_dl(module_id_t module_id,
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||
const int alloc = nr_acknack_scheduling(module_id, iterator->UE, frame, slot, r_pucch, 0);
|
||||
|
||||
if (alloc<0) {
|
||||
LOG_D(NR_MAC,
|
||||
"could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
UE_id,
|
||||
"could not find PUCCH for %04x@%d.%d\n",
|
||||
rnti,
|
||||
frame,
|
||||
slot);
|
||||
@@ -896,35 +894,28 @@ void pf_dl(module_id_t module_id,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE
|
||||
* and PUCCH */
|
||||
max_num_ue--;
|
||||
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(mac,
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
|
||||
if (max_num_ue < 0) return;
|
||||
|
||||
/* MCS has been set above */
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
if (ps->nrOfLayers != layers[UE_id] || ps->time_domain_allocation != tda) {
|
||||
if (ps->nrOfLayers != iterator->UE->layers || ps->time_domain_allocation != tda ) {
|
||||
nr_set_pdsch_semi_static(sib1,
|
||||
scc,
|
||||
UE_info->CellGroup[UE_id],
|
||||
iterator->UE->CellGroup,
|
||||
sched_ctrl->active_bwp,
|
||||
bwpd,
|
||||
tda,
|
||||
layers[UE_id],
|
||||
iterator->UE->layers,
|
||||
sched_ctrl,
|
||||
ps);
|
||||
}
|
||||
@@ -969,21 +960,281 @@ void pf_dl(module_id_t module_id,
|
||||
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
|
||||
|
||||
remainUEs--;
|
||||
iterator++;
|
||||
}
|
||||
}
|
||||
|
||||
void pf_dl_qos(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
NR_UE_info_t **UE_list,
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint16_t *rballoc_mask) {
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
||||
// UEs that could be scheduled
|
||||
UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
|
||||
int remainUEs=max_num_ue;
|
||||
int curUE=0;
|
||||
|
||||
/* Loop UE_info->list to check retransmission */
|
||||
UEs_iterator(UE_list, UE) {
|
||||
if (UE->Msg4_ACKed != true)
|
||||
continue;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||
sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
UE->layers = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
|
||||
/* Calculate Throughput */
|
||||
const float a = 0.0005f; // corresponds to 200ms window
|
||||
const uint32_t b = UE->mac_stats.dlsch_current_bytes;
|
||||
UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b;
|
||||
|
||||
/* retransmission */
|
||||
if (sched_pdsch->dl_harq_pid >= 0) {
|
||||
/* Allocate retransmission */
|
||||
bool r = allocate_dl_retransmission(module_id, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pdsch->dl_harq_pid);
|
||||
|
||||
if (!r) {
|
||||
LOG_D(NR_MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs--;
|
||||
|
||||
if (remainUEs == 0)
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
return;
|
||||
} else {
|
||||
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
|
||||
if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024)
|
||||
continue;
|
||||
|
||||
/* QoS */
|
||||
uint64_t aggregated_pl = 0; // aggregated priority level
|
||||
for (uint8_t idx = 0; idx < sched_ctrl->dl_lc_num; idx++) {
|
||||
uint8_t lcid = sched_ctrl->dl_lc_ids[idx];
|
||||
if (lcid < 4) {
|
||||
// giving highest priority to SRBs
|
||||
aggregated_pl += 1;
|
||||
continue;
|
||||
}
|
||||
for (uint8_t i = 0; i < 26; i++) {
|
||||
if (fiveqi_idx[i] == sched_ctrl->nr_QoS_config[lcid - 4].fiveQI) {
|
||||
aggregated_pl += table_5_6_4_1[i][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate coeff */
|
||||
set_dl_mcs(sched_pdsch,sched_ctrl,&mac->dl_max_mcs,ps->mcsTableIdx);
|
||||
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE, ps->mcsTableIdx);
|
||||
UE->layers = set_dl_nrOfLayers(sched_ctrl);
|
||||
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
uint32_t tbs = nr_compute_tbs(Qm,
|
||||
R,
|
||||
1, /* rbSize */
|
||||
10, /* hypothetical number of slots */
|
||||
0, /* N_PRB_DMRS * N_DMRS_SLOT */
|
||||
0 /* N_PRB_oh, 0 for initialBWP */,
|
||||
0 /* tb_scaling */,
|
||||
UE->layers) >> 3;
|
||||
float coeff_ue = (float) tbs / (UE->dl_thr_ue * aggregated_pl);
|
||||
LOG_D(NR_MAC,"UE %04x b %d, thr_ue %f, tbs %d, coeff_ue %f\n", UE->rnti, b, UE->dl_thr_ue, tbs, UE->dl_coeff_ue);
|
||||
/* Create UE_sched list for UEs eligible for new transmission*/
|
||||
UE_sched[curUE].coef=coeff_ue;
|
||||
UE_sched[curUE].UE=UE;
|
||||
curUE++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
|
||||
UEsched_t *iterator=UE_sched;
|
||||
|
||||
const int min_rbSize = 5;
|
||||
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) {
|
||||
|
||||
NR_CellGroupConfig_t *cg = iterator->UE->CellGroup;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated ?
|
||||
cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd =
|
||||
cg &&
|
||||
cg->spCellConfig &&
|
||||
cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
|
||||
const uint16_t rnti = iterator->UE->rnti;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ?
|
||||
RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 :
|
||||
NULL;
|
||||
|
||||
NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp,
|
||||
RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon,
|
||||
sib1);
|
||||
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ?
|
||||
sched_ctrl->coreset->controlResourceSetId :
|
||||
RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
const uint16_t bwpSize = coresetid == 0 ?
|
||||
RC.nrmac[module_id]->cset0_bwp_size :
|
||||
NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
int rbStart = 0; // start wrt BWPstart
|
||||
|
||||
if (sched_ctrl->available_dl_harq.head < 0) {
|
||||
LOG_D(MAC, "RNTI %04x has no free HARQ process, skipping\n", iterator->UE->rnti);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti);
|
||||
uint8_t nr_of_candidates;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(mac,
|
||||
/* CC_id = */ 0,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d could not find CCE for DL DCI RNTI %04x\n", frame, slot, rnti);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
|
||||
* allocation after CCE alloc fail would be more complex) */
|
||||
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, iterator->UE, frame, slot, r_pucch, 0);
|
||||
|
||||
if (alloc<0) {
|
||||
LOG_D(NR_MAC,
|
||||
"could not find PUCCH for %04x@%d.%d\n",
|
||||
rnti,
|
||||
frame,
|
||||
slot);
|
||||
mac->pdcch_cand[cid]--;
|
||||
continue;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(mac,
|
||||
/* CC_id = */ 0,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
sched_ctrl->aggregation_level);
|
||||
|
||||
/* MCS has been set above */
|
||||
const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp ?
|
||||
sched_ctrl->active_bwp->bwp_Id : 0][slot];
|
||||
AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
if (ps->nrOfLayers != iterator->UE->layers || ps->time_domain_allocation != tda ) {
|
||||
nr_set_pdsch_semi_static(sib1,
|
||||
scc,
|
||||
iterator->UE->CellGroup,
|
||||
sched_ctrl->active_bwp,
|
||||
bwpd,
|
||||
tda,
|
||||
iterator->UE->layers,
|
||||
sched_ctrl,
|
||||
ps);
|
||||
}
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
|
||||
// Freq-demain allocation
|
||||
while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap)
|
||||
rbStart++;
|
||||
|
||||
uint16_t max_rbSize = 1;
|
||||
|
||||
while (rbStart + max_rbSize < bwpSize && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == slbitmap)
|
||||
max_rbSize++;
|
||||
|
||||
sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
sched_pdsch->pucch_allocation = alloc;
|
||||
uint32_t TBS = 0;
|
||||
uint16_t rbSize;
|
||||
// Fix me: currently, the RLC does not give us the total number of PDUs
|
||||
// awaiting. Therefore, for the time being, we put a fixed overhead of 12
|
||||
// (for 4 PDUs) and optionally + 2 for TA. Once RLC gives the number of
|
||||
// PDUs, we replace with 3 * numPDUs
|
||||
const int oh = 3 * 4 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
|
||||
//const int oh = 3 * sched_ctrl->dl_pdus_total + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
|
||||
nr_find_nb_rb(sched_pdsch->Qm,
|
||||
sched_pdsch->R,
|
||||
ps->nrOfLayers,
|
||||
ps->nrOfSymbols,
|
||||
ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
|
||||
sched_ctrl->num_total_bytes + oh,
|
||||
min_rbSize,
|
||||
max_rbSize,
|
||||
&TBS,
|
||||
&rbSize);
|
||||
sched_pdsch->rbSize = rbSize;
|
||||
sched_pdsch->rbStart = rbStart;
|
||||
sched_pdsch->tb_size = TBS;
|
||||
/* transmissions: directly allocate */
|
||||
n_rb_sched -= sched_pdsch->rbSize;
|
||||
|
||||
for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
|
||||
rballoc_mask[rb + sched_pdsch->rbStart] ^= slbitmap;
|
||||
|
||||
remainUEs--;
|
||||
iterator++;
|
||||
}
|
||||
}
|
||||
|
||||
void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
if (UE_info->num_UEs == 0)
|
||||
if (UE_info->list[0] == NULL)
|
||||
return;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
const int CC_id = 0;
|
||||
/* Get bwpSize and TDAfrom the first UE */
|
||||
/* This is temporary and it assumes all UEs have the same BWP and TDA*/
|
||||
int UE_id = UE_info->list.head;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_info_t *UE=UE_info->list[0];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0;
|
||||
|
||||
if (!RC.nrmac[module_id]->preferred_dl_tda[bwp_id])
|
||||
@@ -1005,10 +1256,10 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
sib1);
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
UE_info->CellGroup[UE_id] &&
|
||||
UE_info->CellGroup[UE_id]->spCellConfig &&
|
||||
UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated ?
|
||||
UE_info->CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
UE->CellGroup &&
|
||||
UE->CellGroup->spCellConfig &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated ?
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL;
|
||||
|
||||
const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId;
|
||||
|
||||
@@ -1037,7 +1288,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
pf_dl(module_id,
|
||||
frame,
|
||||
slot,
|
||||
&UE_info->list,
|
||||
UE_info->list,
|
||||
MAX_MOBILES_PER_GNB,
|
||||
n_rb_sched,
|
||||
rballoc_mask);
|
||||
@@ -1084,18 +1335,17 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
||||
const int CC_id = 0;
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
NR_UEs_t *UE_info = &gNB_mac->UE_info;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
NR_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];
|
||||
UEs_iterator(UE_info->list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue;
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
UE->mac_stats.dlsch_current_bytes = 0;
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwpd =
|
||||
cg &&
|
||||
@@ -1109,13 +1359,13 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
* If we add the CE, ta_apply will be reset */
|
||||
if (frame == (sched_ctrl->ta_frame + 10) % 1024) {
|
||||
sched_ctrl->ta_apply = true; /* the timer is reset once TA CE is scheduled */
|
||||
LOG_D(NR_MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
|
||||
LOG_D(NR_MAC, "[UE %04x][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE->rnti, frame, slot);
|
||||
}
|
||||
|
||||
if (sched_pdsch->rbSize <= 0)
|
||||
continue;
|
||||
|
||||
const rnti_t rnti = UE_info->rnti[UE_id];
|
||||
const rnti_t rnti = UE->rnti;
|
||||
/* pre-computed PDSCH values that only change if time domain
|
||||
* allocation/DMRS parameters change. Updated in the preprocessor through
|
||||
* nr_set_pdsch_semi_static() */
|
||||
@@ -1131,8 +1381,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
/* PP has not selected a specific HARQ Process, get a new one */
|
||||
current_harq_pid = sched_ctrl->available_dl_harq.head;
|
||||
AssertFatal(current_harq_pid >= 0,
|
||||
"no free HARQ process available for UE %d\n",
|
||||
UE_id);
|
||||
"no free HARQ process available for UE %04x\n",
|
||||
UE->rnti);
|
||||
remove_front_nr_list(&sched_ctrl->available_dl_harq);
|
||||
sched_pdsch->dl_harq_pid = current_harq_pid;
|
||||
} else {
|
||||
@@ -1152,12 +1402,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
harq->feedback_frame = pucch->frame;
|
||||
harq->feedback_slot = pucch->ul_slot;
|
||||
harq->is_waiting = true;
|
||||
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
|
||||
UE->mac_stats.dlsch_rounds[harq->round]++;
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d [DLSCH/PDSCH/PUCCH] UE %d RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
|
||||
"%4d.%2d [DLSCH/PDSCH/PUCCH] RNTI %04x DCI L %d start %3d RBs %3d startSymbol %2d nb_symbol %2d dmrspos %x MCS %2d nrOfLayers %d TBS %4d HARQ PID %2d round %d RV %d NDI %d dl_data_to_ULACK %d (%d.%d) PUCCH allocation %d TPC %d\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id,
|
||||
rnti,
|
||||
sched_ctrl->aggregation_level,
|
||||
sched_pdsch->rbStart,
|
||||
@@ -1200,7 +1449,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
|
||||
dl_req->nPDUs += 1;
|
||||
pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
|
||||
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %d, bwp %d, cs %d\n",UE_id,bwpid,coresetid);
|
||||
LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n",UE->rnti,bwpid,coresetid);
|
||||
NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset;
|
||||
nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch);
|
||||
gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu;
|
||||
@@ -1392,17 +1641,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
* from RLC or encode MAC CEs. The TX_req structure is filled below
|
||||
* or copy data to FAPI structures */
|
||||
LOG_D(NR_MAC,
|
||||
"%d.%2d DL retransmission UE %d/RNTI %04x HARQ PID %d round %d NDI %d\n",
|
||||
"%d.%2d DL retransmission RNTI %04x HARQ PID %d round %d NDI %d\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id,
|
||||
rnti,
|
||||
current_harq_pid,
|
||||
harq->round,
|
||||
harq->ndi);
|
||||
AssertFatal(harq->sched_pdsch.tb_size == TBS,
|
||||
"UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
||||
UE_id,
|
||||
"UE %04x mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
||||
UE->rnti,
|
||||
current_harq_pid);
|
||||
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
|
||||
@@ -1474,7 +1722,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
lcid_bytes += len;
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += lcid_bytes;
|
||||
UE->mac_stats.lc_bytes_tx[lcid] += lcid_bytes;
|
||||
}
|
||||
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
|
||||
/* we will need the large header, phy-test typically allocates all
|
||||
@@ -1512,8 +1760,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
buf=bufEnd;
|
||||
}
|
||||
|
||||
UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS;
|
||||
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
|
||||
UE->mac_stats.dlsch_total_bytes += TBS;
|
||||
UE->mac_stats.dlsch_current_bytes = TBS;
|
||||
/* save retransmission information */
|
||||
harq->sched_pdsch = *sched_pdsch;
|
||||
/* save which time allocation has been used, to be used on
|
||||
@@ -1525,10 +1773,10 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
sched_ctrl->ta_apply = false;
|
||||
sched_ctrl->ta_frame = frame;
|
||||
LOG_D(NR_MAC,
|
||||
"%d.%2d UE %d TA scheduled, resetting TA frame\n",
|
||||
"%d.%2d UE %04x TA scheduled, resetting TA frame\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id);
|
||||
UE->rnti);
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
|
||||
@@ -152,8 +152,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
NrOfSymbols = NrOfSymbols_tmp;
|
||||
StartSymbolIndex = StartSymbolIndex_tmp;
|
||||
mappingtype = mappingtype_tmp;
|
||||
// k0 = *scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0;
|
||||
// time_domain_assignment = i;
|
||||
}
|
||||
}
|
||||
AssertFatal(StartSymbolIndex>=0,"StartSymbolIndex is negative\n");
|
||||
@@ -165,78 +163,6 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
|
||||
StartSymbolIndex,
|
||||
mappingtype, 1);
|
||||
|
||||
/*
|
||||
AssertFatal(k0==0,"k0 is not zero for Initial DL BWP TimeDomain Alloc\n");
|
||||
nr_configure_css_dci_initial(pdcch_pdu_rel15,
|
||||
scs,
|
||||
scs,
|
||||
FR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
sfn_sf, slotP,
|
||||
slots_per_frame,
|
||||
dlBWP_carrier_bandwidth);
|
||||
|
||||
|
||||
pdu_rel15->frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
dlBWP_carrier_bandwidth);
|
||||
pdu_rel15->time_domain_assignment = time_domain_assignment;
|
||||
|
||||
pdu_rel15->vrb_to_prb_mapping = 1;
|
||||
pdu_rel15->mcs = 9;
|
||||
pdu_rel15->tb_scaling = 1;
|
||||
|
||||
pdu_rel15->ra_preamble_index = 25;
|
||||
pdu_rel15->format_indicator = 1;
|
||||
pdu_rel15->ndi = 1;
|
||||
pdu_rel15->rv = 0;
|
||||
pdu_rel15->harq_pid = 0;
|
||||
pdu_rel15->dai = 2;
|
||||
pdu_rel15->tpc = 2;
|
||||
pdu_rel15->pucch_resource_indicator = 7;
|
||||
pdu_rel15->pdsch_to_harq_feedback_timing_indicator = 7;
|
||||
|
||||
LOG_D(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n",
|
||||
pdu_rel15->frequency_domain_assignment,
|
||||
pdu_rel15->time_domain_assignment,
|
||||
pdu_rel15->vrb_to_prb_mapping,
|
||||
pdu_rel15->mcs,
|
||||
pdu_rel15->tb_scaling,
|
||||
pdu_rel15->ndi,
|
||||
pdu_rel15->rv);
|
||||
|
||||
params_rel15->rnti = rnti;
|
||||
params_rel15->rnti_type = NFAPI_NR_RNTI_C;
|
||||
params_rel15->dci_format = NFAPI_NR_DL_DCI_FORMAT_1_0;
|
||||
//params_rel15->aggregation_level = 1;
|
||||
LOG_D(MAC, "DCI type 1 params: rnti %x, rnti_type %d, dci_format %d\n \
|
||||
coreset params: mux_pattern %d, n_rb %d, n_symb %d, rb_offset %d \n \
|
||||
ss params : nb_ss_sets_per_slot %d, first symb %d, nb_slots %d, sfn_mod2 %d, first slot %d\n",
|
||||
params_rel15->rnti,
|
||||
params_rel15->rnti_type,
|
||||
params_rel15->dci_format,
|
||||
params_rel15->mux_pattern,
|
||||
params_rel15->n_rb,
|
||||
params_rel15->n_symb,
|
||||
params_rel15->rb_offset,
|
||||
params_rel15->nb_ss_sets_per_slot,
|
||||
params_rel15->first_symbol,
|
||||
params_rel15->nb_slots,
|
||||
params_rel15->sfn_mod2,
|
||||
params_rel15->first_slot);
|
||||
nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, dl_tti_dci_pdu->dci_dl_pdu,0);
|
||||
LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d\n",
|
||||
pdsch_pdu_rel15->rbStart,
|
||||
pdsch_pdu_rel15->rbSize,
|
||||
pdsch_pdu_rel15->StartSymbolIndex,
|
||||
pdsch_pdu_rel15->NrOfSymbols,
|
||||
pdsch_pdu_rel15->nrOfLayers,
|
||||
pdsch_pdu_rel15->NrOfCodewords,
|
||||
pdsch_pdu_rel15->mcsIndex[0]);
|
||||
*/
|
||||
|
||||
nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2;
|
||||
|
||||
TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
|
||||
@@ -266,20 +192,15 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
{
|
||||
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
|
||||
return;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0];
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
AssertFatal(UE_info->active[UE_id],
|
||||
"%s(): expected UE %d to be active\n",
|
||||
__func__,
|
||||
UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
const int tda = sched_ctrl->active_bwp ? RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot] : 1;
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
ps->nrOfLayers = target_dl_Nl;
|
||||
if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl)
|
||||
nr_set_pdsch_semi_static(NULL, scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
|
||||
nr_set_pdsch_semi_static(NULL, scc, UE->CellGroup, sched_ctrl->active_bwp, NULL, tda, target_dl_Nl, sched_ctrl, ps);
|
||||
|
||||
/* find largest unallocated chunk */
|
||||
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
|
||||
@@ -314,7 +235,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
sched_ctrl->dl_lc_num = 1;
|
||||
const int lcid = DL_SCH_LCID_DTCH;
|
||||
sched_ctrl->dl_lc_ids[sched_ctrl->dl_lc_num - 1] = lcid;
|
||||
const uint16_t rnti = UE_info->rnti[UE_id];
|
||||
const uint16_t rnti = UE->rnti;
|
||||
/* update sched_ctrl->num_total_bytes so that postprocessor schedules data,
|
||||
* if available */
|
||||
sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id,
|
||||
@@ -341,7 +262,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
@@ -352,17 +273,16 @@ void nr_preprocessor_phytest(module_id_t module_id,
|
||||
Y);
|
||||
|
||||
AssertFatal(CCEIndex >= 0,
|
||||
"%s(): could not find CCE for UE %d\n",
|
||||
"%s(): could not find CCE for UE %04x\n",
|
||||
__func__,
|
||||
UE_id);
|
||||
UE->rnti);
|
||||
|
||||
int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, CCEIndex);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot, r_pucch, 0);
|
||||
const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0);
|
||||
if (alloc < 0) {
|
||||
LOG_D(MAC,
|
||||
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
|
||||
"%s(): could not find PUCCH for UE %04x@%d.%d\n",
|
||||
__func__,
|
||||
UE_id,
|
||||
rnti,
|
||||
frame,
|
||||
slot);
|
||||
@@ -419,19 +339,16 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
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;
|
||||
NR_UE_info_t *UE = nr_mac->UE_info.list[0];
|
||||
|
||||
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)
|
||||
AssertFatal(nr_mac->UE_info.list[1] == NULL,
|
||||
"cannot handle more than one UE\n");
|
||||
if (UE == NULL)
|
||||
return false;
|
||||
|
||||
const int UE_id = 0;
|
||||
const int CC_id = 0;
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1;
|
||||
if (tda < 0)
|
||||
@@ -509,7 +426,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_
|
||||
AssertFatal(nr_of_candidates>0,"nr_of_candidates is 0\n");
|
||||
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
|
||||
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
CC_id,
|
||||
|
||||
@@ -270,7 +270,7 @@ NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(
|
||||
}
|
||||
|
||||
|
||||
NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
void *bwp,
|
||||
NR_SearchSpace_t *ss,
|
||||
@@ -280,7 +280,7 @@ NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space
|
||||
NR_ControlResourceSet_t *coreset;
|
||||
if(coreset_id == 0) {
|
||||
coreset = RC.nrmac[module_idP]->sched_ctrlCommon->coreset; // this is coreset 0
|
||||
coreset = nrmac->sched_ctrlCommon->coreset; // this is coreset 0
|
||||
} else if (bwp) {
|
||||
coreset = ((NR_BWP_Downlink_t*)bwp)->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
|
||||
} else if (scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet) {
|
||||
@@ -580,20 +580,15 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
|
||||
bwpd = (NR_BWP_DownlinkDedicated_t*)bwpd0;
|
||||
}
|
||||
|
||||
// Prevent gNB to enable 256QAM table while the RRCProcessing timer is running.
|
||||
// For example, after the RRC created RRC Reconfiguration message we need to prevent gNB to apply another MCS table
|
||||
// before the RRC Reconfiguration being received by the UE, otherwise UE will not be able to decode PDSCH
|
||||
// and the connection will drop.
|
||||
if (sched_ctrl->rrc_processing_timer == 0) {
|
||||
if (bwpd &&
|
||||
bwpd->pdsch_Config &&
|
||||
bwpd->pdsch_Config->choice.setup &&
|
||||
bwpd->pdsch_Config->choice.setup->mcs_Table) {
|
||||
if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0) {
|
||||
if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0)
|
||||
ps->mcsTableIdx = 1;
|
||||
} else {
|
||||
else
|
||||
ps->mcsTableIdx = 2;
|
||||
}
|
||||
} else {
|
||||
ps->mcsTableIdx = 0;
|
||||
}
|
||||
@@ -603,6 +598,7 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
|
||||
NR_PDSCH_Config_t *pdsch_Config=NULL;
|
||||
if (bwpd) pdsch_Config = bwpd->pdsch_Config->choice.setup;
|
||||
LOG_D(NR_MAC,"tda %d, ps->time_domain_allocation %d,layers %d, ps->nrOfLayers %d, pdsch_config %p\n",tda,ps->time_domain_allocation,layers,ps->nrOfLayers,pdsch_Config);
|
||||
|
||||
if (ps->time_domain_allocation != tda) {
|
||||
reset_dmrs = true;
|
||||
ps->time_domain_allocation = tda;
|
||||
@@ -2059,10 +2055,11 @@ int extract_length(int startSymbolAndLength) {
|
||||
/*
|
||||
* Dump the UL or DL UE_info into LOG_T(MAC)
|
||||
*/
|
||||
void dump_nr_list(NR_list_t *listP)
|
||||
void dump_nr_list(NR_UE_info_t **list)
|
||||
{
|
||||
for (int j = listP->head; j >= 0; j = listP->next[j])
|
||||
LOG_T(NR_MAC, "NR list node %d => %d\n", j, listP->next[j]);
|
||||
UEs_iterator(list, UE) {
|
||||
LOG_T(NR_MAC, "NR list UEs rntis %04x\n", (*list)->rnti);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2117,7 +2114,7 @@ void destroy_nr_list(NR_list_t *list)
|
||||
{
|
||||
free(list->next);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
* Add an ID to an NR_list at the end, traversing the whole list. Note:
|
||||
* add_tail_nr_list() is a faster alternative, but this implementation ensures
|
||||
@@ -2146,16 +2143,7 @@ void remove_nr_list(NR_list_t *listP, int id)
|
||||
prev = cur;
|
||||
cur = &listP->next[*cur];
|
||||
}
|
||||
if (*cur == -1) {
|
||||
cur = &listP->head;
|
||||
prev=&listP->head;
|
||||
while (*cur != -1 && *cur != id) {
|
||||
LOG_I(NR_MAC,"remove_nr_list : id %d, *cur %d\n",id,*cur);
|
||||
prev = cur;
|
||||
cur = &listP->next[*cur];
|
||||
}
|
||||
AssertFatal(1==0, "ID %d not found in UE_list\n", id);
|
||||
}
|
||||
AssertFatal(*cur != -1, "ID %d not found in UE_list\n", id);
|
||||
int *next = &listP->next[*cur];
|
||||
*cur = listP->next[*cur];
|
||||
*next = -1;
|
||||
@@ -2200,21 +2188,17 @@ void remove_front_nr_list(NR_list_t *listP)
|
||||
listP->tail = -1;
|
||||
}
|
||||
|
||||
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP)
|
||||
NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int UE_id;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info;
|
||||
|
||||
for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) {
|
||||
if (UE_info->active[UE_id]) {
|
||||
if (UE_info->rnti[UE_id] == rntiP) {
|
||||
return UE_id;
|
||||
}
|
||||
UEs_iterator(UEs->list, UE) {
|
||||
if (UE->rnti == rntiP) {
|
||||
LOG_D(NR_MAC,"Search and found rnti: %04x\n", rntiP);
|
||||
return UE;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
LOG_W(NR_MAC,"Search for not existing rnti: %04x\n", rntiP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t get_Y(int cid, int slot, rnti_t rnti) {
|
||||
@@ -2287,120 +2271,163 @@ int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[mod_idP];
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
LOG_I(NR_MAC, "[gNB %d] Adding UE with rnti 0x%04x (num_UEs %d)\n",
|
||||
mod_idP,
|
||||
rntiP,
|
||||
UE_info->num_UEs);
|
||||
dump_nr_list(&UE_info->list);
|
||||
/* hack data to remove UE in the phy */
|
||||
int rnti_to_remove[10];
|
||||
volatile int rnti_to_remove_count;
|
||||
pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (UE_info->active[i]) {
|
||||
LOG_D(NR_MAC,"UE %x is active, skipping\n",rntiP);
|
||||
continue;
|
||||
void deleteUEData(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
destroy_nr_list(&sched_ctrl->available_dl_harq);
|
||||
destroy_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
destroy_nr_list(&sched_ctrl->retrans_dl_harq);
|
||||
destroy_nr_list(&sched_ctrl->available_ul_harq);
|
||||
destroy_nr_list(&sched_ctrl->feedback_ul_harq);
|
||||
destroy_nr_list(&sched_ctrl->retrans_ul_harq);
|
||||
LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti);
|
||||
free(UE);
|
||||
/* hack to remove UE in the phy */
|
||||
if (pthread_mutex_lock(&rnti_to_remove_mutex))
|
||||
exit(1);
|
||||
if (rnti_to_remove_count == 10)
|
||||
exit(1);
|
||||
rnti_to_remove[rnti_to_remove_count] = UE->rnti;
|
||||
LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, UE->rnti);
|
||||
rnti_to_remove_count++;
|
||||
if (pthread_mutex_unlock(&rnti_to_remove_mutex))
|
||||
exit(1);
|
||||
|
||||
/* clear RA process(es?) associated to the UE */
|
||||
for (int cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_COMMON_channels_t *cc = &ccPtr[cc_id];
|
||||
if (cc->ra[i].rnti == UE->rnti) {
|
||||
LOG_D(NR_MAC, "free RA process %d for rnti %04x\n", i, UE->rnti);
|
||||
/* is it enough? */
|
||||
cc->ra[i].cfra = false;
|
||||
cc->ra[i].rnti = 0;
|
||||
cc->ra[i].crnti = 0;
|
||||
}
|
||||
}
|
||||
int UE_id = i;
|
||||
UE_info->num_UEs++;
|
||||
UE_info->active[UE_id] = true;
|
||||
if (CellGroup) UE_info->Msg4_ACKed[UE_id] = true;
|
||||
else UE_info->Msg4_ACKed[UE_id] = false;
|
||||
UE_info->rnti[UE_id] = rntiP;
|
||||
UE_info->CellGroup[UE_id] = CellGroup;
|
||||
add_nr_list(&UE_info->list, UE_id);
|
||||
memset(&UE_info->mac_stats[UE_id], 0, sizeof(NR_mac_stats_t));
|
||||
if (CellGroup &&
|
||||
CellGroup->spCellConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup
|
||||
)
|
||||
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE_info, UE_id, mod_idP);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
memset(sched_ctrl, 0, sizeof(*sched_ctrl));
|
||||
sched_ctrl->set_mcs = true;
|
||||
sched_ctrl->ta_frame = 0;
|
||||
sched_ctrl->ta_update = 31;
|
||||
sched_ctrl->ta_apply = false;
|
||||
sched_ctrl->ul_rssi = 0;
|
||||
sched_ctrl->pucch_consecutive_dtx_cnt = 0;
|
||||
sched_ctrl->pusch_consecutive_dtx_cnt = 0;
|
||||
sched_ctrl->ul_failure = 0;
|
||||
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->sched_srs.srs_scheduled = false;
|
||||
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
|
||||
sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
|
||||
/* Set default BWPs */
|
||||
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
|
||||
if (bwpList) AssertFatal(bwpList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
|
||||
const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0;
|
||||
sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
sched_ctrl->search_space = get_searchspace(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
target_ss);
|
||||
sched_ctrl->coreset = get_coreset(mod_idP, scc,
|
||||
sched_ctrl->active_bwp ? (void*)sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[mod_idP],
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
|
||||
if (ubwpList) AssertFatal(ubwpList->list.count == 1,
|
||||
"uplinkBWP_ToAddModList has %d BWP!\n",
|
||||
ubwpList->list.count);
|
||||
const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
||||
sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL;
|
||||
|
||||
/* get Number of HARQ processes for this UE */
|
||||
if (servingCellConfig) AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
|
||||
"no pdsch-ServingCellConfig found for UE %d\n",
|
||||
UE_id);
|
||||
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
||||
// pdsch == NULL in SA -> will create default (8) number of HARQ processes
|
||||
create_dl_harq_list(sched_ctrl, pdsch);
|
||||
// add all available UL HARQ processes for this UE
|
||||
// nb of ul harq processes not configurable
|
||||
create_nr_list(&sched_ctrl->available_ul_harq, 16);
|
||||
for (int harq = 0; harq < 16; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_ul_harq, 16);
|
||||
create_nr_list(&sched_ctrl->retrans_ul_harq, 16);
|
||||
LOG_D(NR_MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n",
|
||||
mod_idP,
|
||||
UE_id,
|
||||
rntiP);
|
||||
dump_nr_list(&UE_info->list);
|
||||
return (UE_id);
|
||||
}
|
||||
|
||||
// printf("MAC: cannot add new UE for rnti %x\n", rntiP);
|
||||
LOG_E(NR_MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n");
|
||||
dump_nr_list(&UE_info->list);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup)
|
||||
{
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
LOG_I(NR_MAC, "Adding UE with rnti 0x%04x\n",
|
||||
rntiP);
|
||||
dump_nr_list(UE_info->list);
|
||||
|
||||
// We will attach at the end, to mitigate race conditions
|
||||
// This is not good, but we will fix it progressively
|
||||
NR_UE_info_t *UE=calloc(1,sizeof(NR_UE_info_t));
|
||||
if(!UE) {
|
||||
LOG_E(NR_MAC,"want to add UE %04x but the fixed allocated size is full\n",rntiP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UE->rnti = rntiP;
|
||||
UE->CellGroup = CellGroup;
|
||||
|
||||
if (CellGroup)
|
||||
UE->Msg4_ACKed = true;
|
||||
else
|
||||
UE->Msg4_ACKed = false;
|
||||
if (CellGroup &&
|
||||
CellGroup->spCellConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
|
||||
CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup
|
||||
)
|
||||
compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->set_mcs = true;
|
||||
sched_ctrl->ta_frame = 0;
|
||||
sched_ctrl->ta_update = 31;
|
||||
sched_ctrl->ta_apply = false;
|
||||
sched_ctrl->ul_rssi = 0;
|
||||
sched_ctrl->pucch_consecutive_dtx_cnt = 0;
|
||||
sched_ctrl->pusch_consecutive_dtx_cnt = 0;
|
||||
sched_ctrl->ul_failure = 0;
|
||||
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->sched_srs.srs_scheduled = false;
|
||||
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
|
||||
sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
|
||||
/* Set default BWPs */
|
||||
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL;
|
||||
if (bwpList) AssertFatal(bwpList->list.count == 1,
|
||||
"downlinkBWP_ToAddModList has %d BWP!\n",
|
||||
bwpList->list.count);
|
||||
|
||||
const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0;
|
||||
sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL;
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common;
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
sched_ctrl->search_space = get_searchspace(sib1,
|
||||
scc,
|
||||
sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
target_ss);
|
||||
sched_ctrl->coreset = get_coreset(nr_mac, scc,
|
||||
sched_ctrl->active_bwp ? (void*)sched_ctrl->active_bwp->bwp_Dedicated : NULL,
|
||||
sched_ctrl->search_space, target_ss);
|
||||
sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac,
|
||||
sched_ctrl->search_space,
|
||||
sched_ctrl->coreset,
|
||||
scc,
|
||||
genericParameters,
|
||||
NULL);
|
||||
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL;
|
||||
if (ubwpList) AssertFatal(ubwpList->list.count == 1,
|
||||
"uplinkBWP_ToAddModList has %d BWP!\n",
|
||||
ubwpList->list.count);
|
||||
const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0;
|
||||
sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL;
|
||||
|
||||
/* get Number of HARQ processes for this UE */
|
||||
if (servingCellConfig) AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
|
||||
"no pdsch-ServingCellConfig found for UE %04x\n",
|
||||
UE->rnti);
|
||||
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
||||
// pdsch == NULL in SA -> will create default (8) number of HARQ processes
|
||||
create_dl_harq_list(sched_ctrl, pdsch);
|
||||
// add all available UL HARQ processes for this UE
|
||||
// nb of ul harq processes not configurable
|
||||
create_nr_list(&sched_ctrl->available_ul_harq, 16);
|
||||
for (int harq = 0; harq < 16; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_ul_harq, 16);
|
||||
create_nr_list(&sched_ctrl->retrans_ul_harq, 16);
|
||||
|
||||
pthread_mutex_lock(&UE_info->mutex);
|
||||
int i;
|
||||
for(i=0; i<MAX_MOBILES_PER_GNB; i++)
|
||||
if (UE_info->list[i] == NULL) {
|
||||
UE_info->list[i]=UE;
|
||||
break;
|
||||
}
|
||||
if (i==MAX_MOBILES_PER_GNB) {
|
||||
LOG_E(NR_MAC,"Try to add UE but the list is full rnti=%04x", rntiP);
|
||||
deleteUEData(UE, nr_mac->common_channels);
|
||||
return NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&UE_info->mutex);
|
||||
|
||||
LOG_D(NR_MAC, "Add NR rnti %x\n", rntiP);
|
||||
dump_nr_list(UE_info->list);
|
||||
return (UE);
|
||||
}
|
||||
|
||||
void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
const NR_PDSCH_ServingCellConfig_t *pdsch) {
|
||||
@@ -2434,66 +2461,29 @@ void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
}
|
||||
}
|
||||
|
||||
/* hack data to remove UE in the phy */
|
||||
int rnti_to_remove[10];
|
||||
volatile int rnti_to_remove_count;
|
||||
pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
|
||||
void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
|
||||
{
|
||||
int UE_id;
|
||||
int i;
|
||||
int cc_id;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UEs_t *UE_info = &nr_mac->UE_info;
|
||||
pthread_mutex_lock(&UE_info->mutex);
|
||||
UEs_iterator(UE_info->list, UE) {
|
||||
if (UE->rnti==rnti)
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_MOBILES_PER_GNB; i++) {
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC,"Call to del rnti %04x, but not existing\n", rnti);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UE_info->active[i] != TRUE)
|
||||
continue;
|
||||
if (UE_info->rnti[i] != rnti)
|
||||
continue;
|
||||
NR_UE_info_t * newUEs[MAX_MOBILES_PER_GNB+1]={0};
|
||||
int newListIdx=0;
|
||||
for (int i=0; i<MAX_MOBILES_PER_GNB; i++)
|
||||
if(UE_info->list[i])
|
||||
newUEs[newListIdx++]=UE_info->list[i];
|
||||
memcpy(UE_info->list, newUEs, sizeof(UE_info->list));
|
||||
pthread_mutex_unlock(&UE_info->mutex);
|
||||
|
||||
/* UE found, remove it */
|
||||
UE_id = i;
|
||||
|
||||
UE_info->num_UEs--;
|
||||
UE_info->active[UE_id] = FALSE;
|
||||
UE_info->rnti[UE_id] = 0;
|
||||
remove_nr_list(&UE_info->list, UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
destroy_nr_list(&sched_ctrl->available_dl_harq);
|
||||
destroy_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
destroy_nr_list(&sched_ctrl->retrans_dl_harq);
|
||||
destroy_nr_list(&sched_ctrl->available_ul_harq);
|
||||
destroy_nr_list(&sched_ctrl->feedback_ul_harq);
|
||||
destroy_nr_list(&sched_ctrl->retrans_ul_harq);
|
||||
LOG_I(NR_MAC, "[gNB %d] Remove NR UE_id %d: rnti 0x%04x\n",
|
||||
mod_id,
|
||||
UE_id,
|
||||
rnti);
|
||||
|
||||
/* hack to remove UE in the phy */
|
||||
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
|
||||
if (rnti_to_remove_count == 10) exit(1);
|
||||
rnti_to_remove[rnti_to_remove_count] = rnti;
|
||||
LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
|
||||
rnti_to_remove_count++;
|
||||
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
|
||||
}
|
||||
|
||||
/* clear RA process(es?) associated to the UE */
|
||||
for (cc_id = 0; cc_id < NFAPI_CC_MAX; cc_id++) {
|
||||
NR_COMMON_channels_t *cc = &RC.nrmac[mod_id]->common_channels[cc_id];
|
||||
for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
if (cc->ra[i].rnti == rnti) {
|
||||
LOG_D(NR_MAC, "free RA process %d for rnti %d\n", i, rnti);
|
||||
/* is it enough? */
|
||||
cc->ra[i].cfra = false;
|
||||
cc->ra[i].rnti = 0;
|
||||
cc->ra[i].crnti = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
deleteUEData(UE, nr_mac->common_channels);
|
||||
}
|
||||
|
||||
void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) {
|
||||
@@ -2517,20 +2507,18 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
|
||||
}
|
||||
|
||||
|
||||
void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
int UE_id,
|
||||
void get_pdsch_to_harq_feedback( NR_UE_info_t * UE,
|
||||
int bwp_id,
|
||||
NR_SearchSpace__searchSpaceType_PR ss_type,
|
||||
int *max_fb_time,
|
||||
uint8_t *pdsch_to_harq_feedback) {
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
NR_BWP_DownlinkDedicated_t *bwpd=NULL;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd=NULL;
|
||||
|
||||
if (ss_type == NR_SearchSpace__searchSpaceType_PR_ue_Specific) {
|
||||
AssertFatal(CellGroup!=NULL,"Cellgroup is not defined for UE_id %d\n",UE_id);
|
||||
AssertFatal(CellGroup!=NULL,"Cellgroup is not defined for UE %04x\n",UE->rnti);
|
||||
AssertFatal(CellGroup->spCellConfig!=NULL,"Cellgroup->spCellConfig is null\n");
|
||||
AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated!=NULL,"CellGroup->spCellConfig->spCellConfigDedicated is null\n");
|
||||
}
|
||||
@@ -2614,20 +2602,17 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
int n_slots_frame){
|
||||
|
||||
int CC_id = 0;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_list_t *UE_list = &UE_info->list;
|
||||
NR_UEs_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP];
|
||||
uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map;
|
||||
|
||||
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];
|
||||
UEs_iterator(UE_info->list, UE) {
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (sched_ctrl->rrc_processing_timer > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
|
||||
if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated ||
|
||||
!CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue;
|
||||
@@ -2643,6 +2628,7 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
NR_BWP_t *genericParameters = sched_ctrl->active_bwp ?
|
||||
&sched_ctrl->active_bwp->bwp_Common->genericParameters:
|
||||
&gNB_mac->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
|
||||
for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
|
||||
nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
|
||||
NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping;
|
||||
@@ -2818,18 +2804,20 @@ void nr_csirs_scheduling(int Mod_idP,
|
||||
void nr_mac_update_timers(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const NR_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];
|
||||
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
|
||||
UEs_iterator(UE_info->list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (sched_ctrl->rrc_processing_timer > 0) {
|
||||
sched_ctrl->rrc_processing_timer--;
|
||||
if (sched_ctrl->rrc_processing_timer == 0) {
|
||||
LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %d\n", frame, slot, UE_id);
|
||||
LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %04x\n", frame, slot, UE->rnti);
|
||||
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ?
|
||||
RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 :
|
||||
NULL;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
|
||||
NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp;
|
||||
NR_BWP_DownlinkDedicated_t *bwpd = cg &&
|
||||
|
||||
@@ -34,18 +34,17 @@
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int UE_id, NR_SRS_Resource_t *srs_resource) {
|
||||
void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_Resource_t *srs_resource) {
|
||||
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
NR_BWP_t ubwp = sched_ctrl->active_ubwp ?
|
||||
sched_ctrl->active_ubwp->bwp_Common->genericParameters :
|
||||
scc->uplinkConfigCommon->initialUplinkBWP->genericParameters;
|
||||
|
||||
srs_pdu->rnti = UE_info->rnti[UE_id];
|
||||
srs_pdu->rnti = UE->rnti;
|
||||
srs_pdu->handle = 0;
|
||||
srs_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
|
||||
srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);;
|
||||
@@ -82,7 +81,7 @@ void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id, int
|
||||
srs_pdu->t_offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p);
|
||||
}
|
||||
|
||||
void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
|
||||
void nr_fill_nfapi_srs(int module_id, int CC_id, NR_UE_info_t* UE, sub_frame_t slot, NR_SRS_Resource_t *srs_resource) {
|
||||
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][slot];
|
||||
AssertFatal(future_ul_tti_req->n_pdus <
|
||||
@@ -94,7 +93,7 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR
|
||||
memset(srs_pdu, 0, sizeof(nfapi_nr_srs_pdu_t));
|
||||
future_ul_tti_req->n_pdus += 1;
|
||||
|
||||
nr_configure_srs(srs_pdu, module_id, CC_id, UE_id, srs_resource);
|
||||
nr_configure_srs(srs_pdu, module_id, CC_id, UE, srs_resource);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -111,21 +110,19 @@ void nr_fill_nfapi_srs(int module_id, int CC_id, int UE_id, sub_frame_t slot, NR
|
||||
void nr_schedule_srs(int module_id, frame_t frame) {
|
||||
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
const NR_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_UEs_t *UE_info = &nrmac->UE_info;
|
||||
|
||||
UEs_iterator(UE_info->list, UE) {
|
||||
const int CC_id = 0;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
sched_ctrl->sched_srs.frame = -1;
|
||||
sched_ctrl->sched_srs.slot = -1;
|
||||
sched_ctrl->sched_srs.srs_scheduled = false;
|
||||
|
||||
if(!UE_info->Msg4_ACKed[UE_id] || sched_ctrl->rrc_processing_timer > 0) {
|
||||
if(!UE->Msg4_ACKed || sched_ctrl->rrc_processing_timer > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -178,11 +175,11 @@ void nr_schedule_srs(int module_id, frame_t frame) {
|
||||
// Check if UE will transmit the SRS in this frame
|
||||
if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) {
|
||||
LOG_D(NR_MAC,"Scheduling SRS reception for %d.%d\n", frame, offset%n_slots_frame);
|
||||
nr_fill_nfapi_srs(module_id, CC_id, UE_id, offset%n_slots_frame, srs_resource);
|
||||
nr_fill_nfapi_srs(module_id, CC_id, UE, offset%n_slots_frame, srs_resource);
|
||||
sched_ctrl->sched_srs.frame = frame;
|
||||
sched_ctrl->sched_srs.slot = offset%n_slots_frame;
|
||||
sched_ctrl->sched_srs.srs_scheduled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,17 +38,15 @@
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
|
||||
void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const NR_sched_pucch_t *pucch,
|
||||
int UE_id)
|
||||
{
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[mod_id];
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
const NR_sched_pucch_t *pucch,
|
||||
NR_UE_info_t* UE)
|
||||
{
|
||||
nfapi_nr_ul_tti_request_t *future_ul_tti_req =
|
||||
&RC.nrmac[mod_id]->UL_tti_req_ahead[0][pucch->ul_slot];
|
||||
&nrmac->UL_tti_req_ahead[0][pucch->ul_slot];
|
||||
AssertFatal(future_ul_tti_req->SFN == pucch->frame
|
||||
&& future_ul_tti_req->Slot == pucch->ul_slot,
|
||||
"Current %d.%d : future UL_tti_req's frame.slot %4d.%2d does not match PUCCH %4d.%2d\n",
|
||||
@@ -57,8 +55,7 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
future_ul_tti_req->Slot,
|
||||
pucch->frame,
|
||||
pucch->ul_slot);
|
||||
AssertFatal(future_ul_tti_req->n_pdus <
|
||||
sizeof(future_ul_tti_req->pdus_list) / sizeof(future_ul_tti_req->pdus_list[0]),
|
||||
AssertFatal(future_ul_tti_req->n_pdus < sizeofArray(future_ul_tti_req->pdus_list),
|
||||
"Invalid future_ul_tti_req->n_pdus %d\n", future_ul_tti_req->n_pdus);
|
||||
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);
|
||||
@@ -77,9 +74,9 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
pucch->dai_c,
|
||||
pucch->csi_bits,
|
||||
pucch->resource_indicator);
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *cg=UE_info->CellGroup[UE_id];
|
||||
NR_COMMON_channels_t * common_ch=nrmac->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = common_ch->ServingCellConfigCommon;
|
||||
NR_CellGroupConfig_t *cg=UE->CellGroup;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
@@ -88,14 +85,14 @@ void nr_fill_nfapi_pucch(module_id_t mod_id,
|
||||
LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n",
|
||||
frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot);
|
||||
|
||||
const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
const NR_SIB1_t *sib1 = common_ch->sib1 ? common_ch->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
nr_configure_pucch(sib1,
|
||||
pucch_pdu,
|
||||
scc,
|
||||
UE_info->CellGroup[UE_id],
|
||||
UE_info->UE_sched_ctrl[UE_id].active_ubwp,
|
||||
UE->CellGroup,
|
||||
UE->UE_sched_ctrl.active_ubwp,
|
||||
ubwpd,
|
||||
UE_info->rnti[UE_id],
|
||||
UE->rnti,
|
||||
pucch->resource_indicator,
|
||||
pucch->csi_bits,
|
||||
pucch->dai_c,
|
||||
@@ -139,22 +136,18 @@ int diff_rsrp_ssb_csi_meas_10_1_6_1_2[16] = {
|
||||
};
|
||||
|
||||
|
||||
void nr_schedule_pucch(int Mod_idP,
|
||||
void nr_schedule_pucch(gNB_MAC_INST *nrmac,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
|
||||
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slotP / 64], slotP))
|
||||
return;
|
||||
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
const NR_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];
|
||||
UEs_iterator(nrmac->UE_info.list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
const int n = sizeof(sched_ctrl->sched_pucch) / sizeof(*sched_ctrl->sched_pucch);
|
||||
for (int i = 0; i < n; i++) {
|
||||
NR_sched_pucch_t *curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[i];
|
||||
NR_sched_pucch_t *curr_pucch = &UE->UE_sched_ctrl.sched_pucch[i];
|
||||
const uint16_t O_ack = curr_pucch->dai_c;
|
||||
const uint16_t O_csi = curr_pucch->csi_bits;
|
||||
const uint8_t O_sr = curr_pucch->sr_flag;
|
||||
@@ -162,9 +155,12 @@ void nr_schedule_pucch(int Mod_idP,
|
||||
|| frameP != curr_pucch->frame
|
||||
|| slotP != curr_pucch->ul_slot)
|
||||
continue;
|
||||
if (O_csi > 0) LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %d in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
|
||||
i,UE_id,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi);
|
||||
nr_fill_nfapi_pucch(Mod_idP, frameP, slotP, curr_pucch, UE_id);
|
||||
|
||||
if (O_csi > 0)
|
||||
LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
|
||||
i,UE->rnti,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi);
|
||||
nr_fill_nfapi_pucch(nrmac,
|
||||
frameP, slotP, curr_pucch, UE);
|
||||
memset(curr_pucch, 0, sizeof(*curr_pucch));
|
||||
}
|
||||
}
|
||||
@@ -560,7 +556,7 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
|
||||
|
||||
|
||||
//!TODO : same function can be written to handle csi_resources
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP){
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){
|
||||
uint8_t csi_report_id = 0;
|
||||
uint8_t nb_resources = 0;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type;
|
||||
@@ -572,7 +568,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
|
||||
for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){
|
||||
struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id];
|
||||
// MAC structure for CSI measurement reports (per UE and per report)
|
||||
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id];
|
||||
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
|
||||
// csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration
|
||||
// (either CSI-RS or SSB)
|
||||
csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement;
|
||||
@@ -657,24 +653,22 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
|
||||
}
|
||||
|
||||
|
||||
uint16_t nr_get_csi_bitlen(int Mod_idP,
|
||||
int UE_id,
|
||||
uint16_t nr_get_csi_bitlen(NR_UE_info_t *UE,
|
||||
uint8_t csi_report_id) {
|
||||
|
||||
uint16_t csi_bitlen = 0;
|
||||
uint16_t max_bitlen = 0;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
L1_RSRP_bitlen_t * CSI_report_bitlen = NULL;
|
||||
CSI_Meas_bitlen_t * csi_meas_bitlen = NULL;
|
||||
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type||
|
||||
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type){
|
||||
CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type||
|
||||
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type){
|
||||
CSI_report_bitlen = &(UE->csi_report_template[csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
|
||||
CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
|
||||
(CSI_report_bitlen->nb_ssbri_cri -1 )));
|
||||
} else{
|
||||
csi_meas_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
csi_meas_bitlen = &(UE->csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
|
||||
uint16_t temp_bitlen;
|
||||
for (int i=0; i<8; i++) {
|
||||
temp_bitlen = (csi_meas_bitlen->cri_bitlen+
|
||||
@@ -700,11 +694,10 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
const NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
UEs_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) {
|
||||
const NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) {
|
||||
continue;
|
||||
}
|
||||
@@ -716,13 +709,13 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||
if (sched_ctrl->active_ubwp) {
|
||||
pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
} else if (RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id] &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||
pucch_Config = RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
} else if (UE->CellGroup &&
|
||||
UE->CellGroup->spCellConfig &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||
pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
}
|
||||
|
||||
|
||||
@@ -757,13 +750,13 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
&& !curr_pucch->sr_flag
|
||||
&& curr_pucch->dai_c == 0,
|
||||
"PUCCH not free at index 1 for UE %04x\n",
|
||||
UE_info->rnti[UE_id]);
|
||||
UE->rnti);
|
||||
curr_pucch->r_pucch = -1;
|
||||
curr_pucch->frame = frame;
|
||||
curr_pucch->ul_slot = sched_slot;
|
||||
curr_pucch->resource_indicator = res_index;
|
||||
curr_pucch->csi_bits +=
|
||||
nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id);
|
||||
nr_get_csi_bitlen(UE,csi_report_id);
|
||||
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
@@ -815,37 +808,35 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static void handle_dl_harq(module_id_t mod_id,
|
||||
int UE_id,
|
||||
static void handle_dl_harq(NR_UE_info_t * UE,
|
||||
int8_t harq_pid,
|
||||
bool success)
|
||||
bool success,
|
||||
int harq_round_max)
|
||||
{
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info;
|
||||
NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[harq_pid];
|
||||
NR_UE_harq_t *harq = &UE->UE_sched_ctrl.harq_processes[harq_pid];
|
||||
harq->feedback_slot = -1;
|
||||
harq->is_waiting = false;
|
||||
if (success) {
|
||||
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid);
|
||||
add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
|
||||
harq->round = 0;
|
||||
harq->ndi ^= 1;
|
||||
} else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
||||
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid);
|
||||
|
||||
} else if (harq->round >= harq_round_max - 1) {
|
||||
add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid);
|
||||
harq->round = 0;
|
||||
harq->ndi ^= 1;
|
||||
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
stats->dlsch_errors++;
|
||||
LOG_D(NR_MAC, "retransmission error for UE %d (total %"PRIu64")\n", UE_id, stats->dlsch_errors);
|
||||
LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, stats->dlsch_errors);
|
||||
} else {
|
||||
LOG_D(PHY,"NACK for: pid %d, ue %x\n",harq_pid, UE_id);
|
||||
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].retrans_dl_harq, harq_pid);
|
||||
LOG_D(PHY,"NACK for: pid %d, ue %04x\n",harq_pid, UE->rnti);
|
||||
add_tail_nr_list(&UE->UE_sched_ctrl.retrans_dl_harq, harq_pid);
|
||||
harq->round++;
|
||||
}
|
||||
}
|
||||
|
||||
int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, int UE_id) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id] ;
|
||||
int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * UE) {
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
|
||||
NR_TCI_State_t *tci =NULL;
|
||||
int i;
|
||||
@@ -870,9 +861,8 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, int Mod_idP, i
|
||||
return -1;
|
||||
}
|
||||
|
||||
int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_id) {
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id] ;
|
||||
int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) {
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup ;
|
||||
int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count;
|
||||
NR_TCI_State_t *tci =NULL;
|
||||
NR_TCI_StateId_t *tci_id = NULL;
|
||||
@@ -932,7 +922,7 @@ int get_diff_rsrp(uint8_t index, int strongest_rsrp) {
|
||||
//identifies the target SSB Beam index
|
||||
//keeps the required date for PDCCH and PDSCH TCI state activation/deactivation CE consutruction globally
|
||||
//handles triggering of PDCCH and PDSCH MAC CEs
|
||||
void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
void tci_handling(NR_UE_info_t * UE, frame_t frame, slot_t slot) {
|
||||
|
||||
int strongest_ssb_rsrp = 0;
|
||||
int cqi_idx = 0;
|
||||
@@ -944,15 +934,14 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
int ssb_index[MAX_NUM_SSB] = {0};
|
||||
int ssb_rsrp[MAX_NUM_SSB] = {0};
|
||||
uint8_t idx = 0;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl=&UE->UE_sched_ctrl;
|
||||
int bwp_id = sched_ctrl->active_bwp ? 1 : 0;
|
||||
NR_CellGroupConfig_t *CellGroup = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *CellGroup = UE->CellGroup;
|
||||
NR_BWP_Downlink_t *bwp = bwp_id>0 ?
|
||||
sched_ctrl->active_bwp:
|
||||
NULL;
|
||||
|
||||
|
||||
//bwp indicator
|
||||
int n_dl_bwp=0;
|
||||
if (CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
@@ -960,7 +949,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
n_dl_bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count;
|
||||
|
||||
uint8_t nr_ssbri_cri = 0;
|
||||
uint8_t nb_of_csi_ssb_report = UE_info->csi_report_template[UE_id][cqi_idx].nb_of_csi_ssb_report;
|
||||
uint8_t nb_of_csi_ssb_report = UE->csi_report_template[cqi_idx].nb_of_csi_ssb_report;
|
||||
int better_rsrp_reported = -140-(-0); /*minimum_measured_RSRP_value - minimum_differntail_RSRP_value*///considering the minimum RSRP value as better RSRP initially
|
||||
uint8_t diff_rsrp_idx = 0;
|
||||
uint8_t i, j;
|
||||
@@ -1031,7 +1020,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
The length of the field is 7 bits
|
||||
*/
|
||||
if(sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.coresetId == 0) {
|
||||
int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id);
|
||||
int tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index[target_ssb_beam_index], UE);
|
||||
|
||||
if( tci_state_id != -1)
|
||||
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
|
||||
@@ -1041,7 +1030,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
int flag = 0;
|
||||
|
||||
for(i =0; ssb_index_sorted[i]!=0; i++) {
|
||||
tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i], Mod_idP, UE_id) ;
|
||||
tci_state_id = checkTargetSSBInFirst64TCIStates_pdschConfig(ssb_index_sorted[i],UE) ;
|
||||
|
||||
if(tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
|
||||
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
|
||||
@@ -1055,7 +1044,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], Mod_idP, UE_id);
|
||||
int tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index[target_ssb_beam_index], UE);
|
||||
|
||||
if (tci_state_id !=-1)
|
||||
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
|
||||
@@ -1065,7 +1054,7 @@ void tci_handling(module_id_t Mod_idP, int UE_id, frame_t frame, slot_t slot) {
|
||||
int flag = 0;
|
||||
|
||||
for(i =0; ssb_index_sorted[i]!=0; i++) {
|
||||
tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], Mod_idP, UE_id);
|
||||
tci_state_id = checkTargetSSBInTCIStates_pdcchConfig(ssb_index_sorted[i], UE);
|
||||
|
||||
if( tci_state_id != -1 && ssb_rsrp_sorted[i] > ssb_rsrp[curr_ssb_beam_index] && ssb_rsrp_sorted[i] - ssb_rsrp[curr_ssb_beam_index] > L1_RSRP_HYSTERIS) {
|
||||
sched_ctrl->UE_mac_ce_ctrl.pdcch_state_ind.tciStateId = tci_state_id;
|
||||
@@ -1128,15 +1117,14 @@ uint8_t pickandreverse_bits(uint8_t *payload, uint16_t bitlen, uint8_t start_bit
|
||||
}
|
||||
|
||||
|
||||
void evaluate_rsrp_report(NR_UE_info_t *UE_info,
|
||||
void evaluate_rsrp_report(NR_UE_info_t *UE,
|
||||
NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
int UE_id,
|
||||
uint8_t csi_report_id,
|
||||
uint8_t *payload,
|
||||
int *cumul_bits,
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type){
|
||||
|
||||
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id];
|
||||
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
|
||||
uint8_t cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen;
|
||||
uint16_t curr_payload;
|
||||
|
||||
@@ -1188,7 +1176,7 @@ void evaluate_rsrp_report(NR_UE_info_t *UE_info,
|
||||
}
|
||||
csi_report->nb_of_csi_ssb_report++;
|
||||
int strongest_ssb_rsrp = get_measured_rsrp(sched_ctrl->CSI_report.ssb_cri_report.RSRP);
|
||||
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
// including ssb rsrp in mac stats
|
||||
stats->cumul_rsrp += strongest_ssb_rsrp;
|
||||
stats->num_rsrp_meas++;
|
||||
@@ -1320,22 +1308,19 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu,
|
||||
frame_t frame,
|
||||
slot_t slot,
|
||||
int UE_id,
|
||||
module_id_t Mod_idP) {
|
||||
NR_UE_info_t *UE,
|
||||
NR_ServingCellConfigCommon_t *scc) {
|
||||
|
||||
/** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */
|
||||
NR_ServingCellConfigCommon_t *scc =
|
||||
RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload;
|
||||
uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len;
|
||||
NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING;
|
||||
NR_UE_info_t *UE_info = &(RC.nrmac[Mod_idP]->UE_info);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
int cumul_bits = 0;
|
||||
int r_index = -1;
|
||||
for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) {
|
||||
nr_csi_report_t *csi_report = &UE_info->csi_report_template[UE_id][csi_report_id];
|
||||
nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id];
|
||||
csi_report->nb_of_csi_ssb_report = 0;
|
||||
uint8_t cri_bitlen = 0;
|
||||
uint8_t ri_bitlen = 0;
|
||||
@@ -1350,10 +1335,10 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
LOG_D(MAC,"SFN/SF:%d/%d reportQuantity type = %d\n",frame,slot,reportQuantity_type);
|
||||
switch(reportQuantity_type){
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP:
|
||||
evaluate_rsrp_report(UE_info,sched_ctrl,UE_id,csi_report_id,payload,&cumul_bits,reportQuantity_type);
|
||||
evaluate_rsrp_report(UE,sched_ctrl,csi_report_id,payload,&cumul_bits,reportQuantity_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP:
|
||||
evaluate_rsrp_report(UE_info,sched_ctrl,UE_id,csi_report_id,payload,&cumul_bits,reportQuantity_type);
|
||||
evaluate_rsrp_report(UE,sched_ctrl,csi_report_id,payload,&cumul_bits,reportQuantity_type);
|
||||
break;
|
||||
case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
|
||||
cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen;
|
||||
@@ -1407,7 +1392,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
}
|
||||
}
|
||||
|
||||
static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, int UE_id)
|
||||
static NR_UE_harq_t *find_harq(frame_t frame, sub_frame_t slot, NR_UE_info_t * UE, int harq_round_max)
|
||||
{
|
||||
/* In case of realtime problems: we can only identify a HARQ process by
|
||||
* timing. If the HARQ process's feedback_frame/feedback_slot is not the one we
|
||||
@@ -1415,7 +1400,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
|
||||
* skip this HARQ process, which is what happens in the loop below.
|
||||
* Similarly, we might be "in advance", in which case we need to skip
|
||||
* this result. */
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
if (pid < 0)
|
||||
return NULL;
|
||||
@@ -1431,7 +1416,7 @@ static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t sl
|
||||
frame,
|
||||
slot);
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
handle_dl_harq(mod_id, UE_id, pid, 0);
|
||||
handle_dl_harq(UE, pid, 0, harq_round_max);
|
||||
pid = sched_ctrl->feedback_dl_harq.head;
|
||||
if (pid < 0)
|
||||
return NULL;
|
||||
@@ -1456,20 +1441,19 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
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) {
|
||||
NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_01->rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_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];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if (((uci_01->pduBitmap >> 1) & 0x01)) {
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
|
||||
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
|
||||
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
|
||||
NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
|
||||
if (!harq) {
|
||||
LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__);
|
||||
break;
|
||||
@@ -1478,8 +1462,8 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value);
|
||||
handle_dl_harq(mod_id, UE_id, pid, harq_value == 0 && harq_confidence == 0);
|
||||
if (harq_confidence == 1) UE_info->mac_stats[UE_id].pucch0_DTX++;
|
||||
handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->harq_round_max);
|
||||
if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1504,19 +1488,21 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
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) {
|
||||
NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, uci_234->rnti);
|
||||
if (!UE) {
|
||||
LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti);
|
||||
return;
|
||||
}
|
||||
AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id],"Cellgroup is null for UE %d/%x\n",UE_id,uci_234->rnti);
|
||||
AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig, "Cellgroup->spCellConfig is null for UE %d/%x\n",UE_id,uci_234->rnti);
|
||||
AssertFatal(RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated, "Cellgroup->spCellConfig->spCellConfigDedicated is null for UE %d/%x\n",UE_id,uci_234->rnti);
|
||||
if ( RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL) return;
|
||||
AssertFatal(UE->CellGroup,"Cellgroup is null for UE %x\n",uci_234->rnti);
|
||||
AssertFatal(UE->CellGroup->spCellConfig,
|
||||
"Cellgroup->spCellConfig is null for UE %x\n",uci_234->rnti);
|
||||
AssertFatal(UE->CellGroup->spCellConfig->spCellConfigDedicated,
|
||||
"Cellgroup->spCellConfig->spCellConfigDedicated is null for UE%x\n",uci_234->rnti);
|
||||
if ( UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL)
|
||||
return;
|
||||
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
|
||||
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];
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig = UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
// tpc (power control)
|
||||
// TODO PUCCH2 SNR computation is not correct -> ignore the following
|
||||
@@ -1529,20 +1515,20 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
|
||||
// iterate over received harq bits
|
||||
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
|
||||
const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
|
||||
NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
|
||||
NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max);
|
||||
if (!harq)
|
||||
break;
|
||||
DevAssert(harq->is_waiting);
|
||||
const int8_t pid = sched_ctrl->feedback_dl_harq.head;
|
||||
remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
|
||||
handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack);
|
||||
handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->harq_round_max);
|
||||
}
|
||||
}
|
||||
if ((uci_234->pduBitmap >> 2) & 0x01) {
|
||||
//API to parse the csi report and store it into sched_ctrl
|
||||
extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE_id, mod_id);
|
||||
extract_pucch_csi_report(csi_MeasConfig, uci_234, frame, slot, UE, RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon);
|
||||
//TCI handling function
|
||||
tci_handling(mod_id, UE_id,frame, slot);
|
||||
tci_handling(UE,frame, slot);
|
||||
}
|
||||
if ((uci_234->pduBitmap >> 3) & 0x01) {
|
||||
//@TODO:Handle CSI Report 2
|
||||
@@ -1610,12 +1596,11 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
// if the function returns -1 it was not possible to schedule acknack
|
||||
// when current pucch is ready to be scheduled nr_fill_nfapi_pucch is called
|
||||
int nr_acknack_scheduling(int mod_id,
|
||||
int UE_id,
|
||||
NR_UE_info_t * UE,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
int r_pucch,
|
||||
int is_common) {
|
||||
|
||||
const int CC_id = 0;
|
||||
const int minfbtime = RC.nrmac[mod_id]->minRXTXTIMEpdsch;
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[CC_id].ServingCellConfigCommon;
|
||||
@@ -1633,8 +1618,8 @@ int nr_acknack_scheduling(int mod_id,
|
||||
* * SR uses format 0 and is allocated in the first UL (mixed) slot (and not
|
||||
* later)
|
||||
* * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
|
||||
NR_CellGroupConfig_t *cg = RC.nrmac[mod_id]->UE_info.CellGroup[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
|
||||
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||
if (sched_ctrl->active_ubwp) {
|
||||
@@ -1669,11 +1654,14 @@ int nr_acknack_scheduling(int mod_id,
|
||||
const int f = pucch->frame;
|
||||
const int s = pucch->ul_slot;
|
||||
LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
|
||||
|
||||
if (!(csi_pucch
|
||||
&& csi_pucch->csi_bits > 0
|
||||
&& csi_pucch->frame == f
|
||||
&& csi_pucch->ul_slot == s))
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id],
|
||||
frame, slot, pucch, UE);
|
||||
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
if(((s + 1)%nr_slots_period) == 0)
|
||||
@@ -1690,7 +1678,9 @@ int nr_acknack_scheduling(int mod_id,
|
||||
&& csi_pucch->ul_slot == pucch->ul_slot
|
||||
&& !csi_pucch->simultaneous_harqcsi) {
|
||||
LOG_D(NR_MAC,"Cannot multiplex csi_pucch for %d.%d\n",csi_pucch->frame,csi_pucch->ul_slot);
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id],
|
||||
frame, slot, csi_pucch, UE);
|
||||
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
pucch->frame = pucch->ul_slot == n_slots_frame - 1 ? (pucch->frame + 1) % 1024 : pucch->frame;
|
||||
if(((pucch->ul_slot + 1)%nr_slots_period) == 0)
|
||||
@@ -1718,7 +1708,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
if (sched_ctrl->active_ubwp) bwp_Id = sched_ctrl->active_ubwp->bwp_Id;
|
||||
|
||||
int max_fb_time = 0;
|
||||
get_pdsch_to_harq_feedback(mod_id, UE_id, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
|
||||
get_pdsch_to_harq_feedback(UE, bwp_Id, ss_type, &max_fb_time, pdsch_to_harq_feedback);
|
||||
|
||||
LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c);
|
||||
/* there is a HARQ. Check whether we can use it for this ACKNACK */
|
||||
@@ -1745,14 +1735,15 @@ int nr_acknack_scheduling(int mod_id,
|
||||
csi_pucch->csi_bits > 0 &&
|
||||
csi_pucch->frame == f &&
|
||||
csi_pucch->ul_slot == s))
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, pucch, UE_id);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id],
|
||||
frame, slot, pucch, UE);
|
||||
memset(pucch, 0, sizeof(*pucch));
|
||||
pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
|
||||
if(((s + 1)%nr_slots_period) == 0)
|
||||
pucch->ul_slot = (s + 1 + first_ul_slot_period) % n_slots_frame;
|
||||
else
|
||||
pucch->ul_slot = (s + 1) % n_slots_frame;
|
||||
return nr_acknack_scheduling(mod_id, UE_id, frame, slot, r_pucch,is_common);
|
||||
return nr_acknack_scheduling(mod_id, UE, frame, slot, r_pucch,is_common);
|
||||
}
|
||||
|
||||
pucch->timing_indicator = i;
|
||||
@@ -1778,10 +1769,11 @@ int nr_acknack_scheduling(int mod_id,
|
||||
((pucch->frame*n_slots_frame + pucch->ul_slot) <
|
||||
(frame*n_slots_frame + slot))) {
|
||||
AssertFatal(pucch->sr_flag + pucch->dai_c == 0,
|
||||
"expected no SR/AckNack for UE %d in %4d.%2d, but has %d/%d for %4d.%2d\n",
|
||||
UE_id, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
|
||||
"expected no SR/AckNack for UE %04x in %4d.%2d, but has %d/%d for %4d.%2d\n",
|
||||
UE->rnti, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
|
||||
const int s = next_ul_slot;
|
||||
pucch->frame = s < n_slots_frame ? frame : (frame + 1) % 1024;
|
||||
|
||||
pucch->ul_slot = s % n_slots_frame;
|
||||
}
|
||||
|
||||
@@ -1829,11 +1821,11 @@ int nr_acknack_scheduling(int mod_id,
|
||||
}
|
||||
if (ind_found==-1) {
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d could not find pdsch_to_harq_feedback for UE %d: earliest "
|
||||
"%4d.%2d could not find pdsch_to_harq_feedback for UE %04x: earliest "
|
||||
"ack slot %d\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id,
|
||||
UE->rnti,
|
||||
pucch->ul_slot);
|
||||
return -1;
|
||||
}
|
||||
@@ -1847,8 +1839,10 @@ int nr_acknack_scheduling(int mod_id,
|
||||
// FIXME currently we support at most 11 bits in pucch2 so skip also in that case
|
||||
if(!csi_pucch->simultaneous_harqcsi
|
||||
|| ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) {
|
||||
|
||||
LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot);
|
||||
nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
|
||||
nr_fill_nfapi_pucch(RC.nrmac[mod_id],
|
||||
frame, slot, csi_pucch, UE);
|
||||
memset(csi_pucch, 0, sizeof(*csi_pucch));
|
||||
/* advance the UL slot information in PUCCH by one so we won't schedule in
|
||||
* the same slot again */
|
||||
@@ -1860,7 +1854,7 @@ int nr_acknack_scheduling(int mod_id,
|
||||
pucch->ul_slot = (s + 1 + first_ul_slot_period) % n_slots_frame;
|
||||
else
|
||||
pucch->ul_slot = (s + 1) % n_slots_frame;
|
||||
return nr_acknack_scheduling(mod_id, UE_id, frame, slot, r_pucch,is_common);
|
||||
return nr_acknack_scheduling(mod_id, UE, frame, slot, r_pucch,is_common);
|
||||
}
|
||||
// multiplexing harq and csi in a pucch
|
||||
else {
|
||||
@@ -1897,29 +1891,26 @@ int nr_acknack_scheduling(int mod_id,
|
||||
}
|
||||
|
||||
|
||||
void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[Mod_idP];
|
||||
if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot))
|
||||
return;
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
|
||||
const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
NR_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];
|
||||
UEs_iterator(nrmac->UE_info.list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if (sched_ctrl->ul_failure==1) continue;
|
||||
NR_PUCCH_Config_t *pucch_Config = NULL;
|
||||
if (sched_ctrl->active_ubwp) {
|
||||
pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup;
|
||||
} else if (RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id] &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
|
||||
RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||
pucch_Config = RC.nrmac[Mod_idP]->UE_info.CellGroup[UE_id]->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
} else if (UE->CellGroup &&
|
||||
UE->CellGroup->spCellConfig &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP &&
|
||||
UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) {
|
||||
pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup;
|
||||
}
|
||||
|
||||
else continue;
|
||||
@@ -1966,7 +1957,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
continue;
|
||||
nfapi_nr_pucch_pdu_t *pdu = &ul_tti_req->pdus_list[i].pucch_pdu;
|
||||
/* check that it is our PUCCH F0. Assuming there can be only one */
|
||||
if (pdu->rnti == UE_info->rnti[UE_id]
|
||||
if (pdu->rnti == UE->rnti
|
||||
&& pdu->format_type == 0 // does not use NR_PUCCH_Resource__format_PR_format0
|
||||
&& pdu->initial_cyclic_shift == pucch_res->format.choice.format0->initialCyclicShift
|
||||
&& pdu->nr_of_symbols == pucch_res->format.choice.format0->nrofSymbols
|
||||
@@ -1976,7 +1967,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
nfapi_allocated = true;
|
||||
break;
|
||||
}
|
||||
else if (pdu->rnti == UE_info->rnti[UE_id]
|
||||
else if (pdu->rnti == UE->rnti
|
||||
&& pdu->format_type == 2 // does not use NR_PUCCH_Resource__format_PR_format0
|
||||
&& pdu->nr_of_symbols == pucch_res->format.choice.format2->nrofSymbols
|
||||
&& pdu->start_symbol_index == pucch_res->format.choice.format2->startingSymbolIndex) {
|
||||
@@ -1986,7 +1977,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
break;
|
||||
|
||||
}
|
||||
else if (pdu->rnti == UE_info->rnti[UE_id]
|
||||
else if (pdu->rnti == UE->rnti
|
||||
&& pdu->format_type == 1 // does not use NR_PUCCH_Resource__format_PR_format0
|
||||
&& pdu->nr_of_symbols == pucch_res->format.choice.format1->nrofSymbols
|
||||
&& pdu->start_symbol_index == pucch_res->format.choice.format1->startingSymbolIndex) {
|
||||
@@ -1996,7 +1987,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
break;
|
||||
|
||||
}
|
||||
else if (pdu->rnti == UE_info->rnti[UE_id]
|
||||
else if (pdu->rnti == UE->rnti
|
||||
&& pdu->format_type == 3 // does not use NR_PUCCH_Resource__format_PR_format0
|
||||
&& pdu->nr_of_symbols == pucch_res->format.choice.format3->nrofSymbols
|
||||
&& pdu->start_symbol_index == pucch_res->format.choice.format3->startingSymbolIndex) {
|
||||
@@ -2006,7 +1997,7 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
break;
|
||||
|
||||
}
|
||||
else if (pdu->rnti == UE_info->rnti[UE_id]
|
||||
else if (pdu->rnti == UE->rnti
|
||||
&& pdu->format_type == 4 // does not use NR_PUCCH_Resource__format_PR_format0
|
||||
&& pdu->nr_of_symbols == pucch_res->format.choice.format4->nrofSymbols
|
||||
&& pdu->start_symbol_index == pucch_res->format.choice.format4->startingSymbolIndex) {
|
||||
@@ -2038,7 +2029,8 @@ void nr_sr_reporting(int Mod_idP, frame_t SFN, sub_frame_t slot)
|
||||
.resource_indicator = found,
|
||||
.r_pucch = -1
|
||||
};
|
||||
nr_fill_nfapi_pucch(Mod_idP, SFN, slot, &sched_sr, UE_id);
|
||||
nr_fill_nfapi_pucch(nrmac,
|
||||
SFN, slot, &sched_sr, UE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,8 +204,8 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub
|
||||
// F: length of L is 0:8 or 1:16 bits wide
|
||||
// R: Reserved bit, set to zero.
|
||||
|
||||
int nr_process_mac_pdu(module_id_t module_idP,
|
||||
int UE_id,
|
||||
int nr_process_mac_pdu( instance_t module_idP,
|
||||
NR_UE_info_t* UE,
|
||||
uint8_t CC_id,
|
||||
frame_t frameP,
|
||||
sub_frame_t slot,
|
||||
@@ -216,11 +216,10 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
uint8_t done = 0;
|
||||
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
if ( pduP[0] != UL_SCH_LCID_PADDING )
|
||||
trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0);
|
||||
trace_NRpdu(DIRECTION_UPLINK, pduP, pdu_len, WS_C_RNTI, UE->rnti, frameP, 0, 0, 0);
|
||||
|
||||
#ifdef ENABLE_MAC_PAYLOAD_DEBUG
|
||||
LOG_I(NR_MAC, "In %s: dumping MAC PDU in %d.%d:\n", __func__, frameP, slot);
|
||||
@@ -317,7 +316,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) {
|
||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
||||
ra->crnti = ((pduP[1]&0xFF)<<8)|(pduP[2]&0xFF);
|
||||
ra->msg3_dcch_dtch = true;
|
||||
LOG_I(NR_MAC, "Received UL_SCH_LCID_C_RNTI with C-RNTI 0x%04x\n", ra->crnti);
|
||||
@@ -378,22 +377,23 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
|
||||
rnti_t crnti = UE_info->rnti[UE_id];
|
||||
int UE_idx = UE_id;
|
||||
rnti_t crnti = UE->rnti;
|
||||
NR_UE_info_t* UE_idx = UE;
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
|
||||
NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[i];
|
||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE_info->rnti[UE_id]) {
|
||||
if (ra->state >= WAIT_Msg3 && ra->rnti == UE->rnti) {
|
||||
uint8_t *next_subpduP = pduP + mac_subheader_len + mac_len;
|
||||
if ((pduP[mac_subheader_len+mac_len] & 0x3F) == UL_SCH_LCID_C_RNTI) {
|
||||
crnti = ((next_subpduP[1]&0xFF)<<8)|(next_subpduP[2]&0xFF);
|
||||
UE_idx = find_nr_UE_id(module_idP, crnti);
|
||||
LOG_W(NR_MAC, " UL_SCH_LCID_SRB for rnti %04x\n", crnti);
|
||||
UE_idx = find_nr_UE(&RC.nrmac[module_idP]->UE_info, crnti);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (UE_info->CellGroup[UE_idx]) {
|
||||
LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: 0x%04x \n", module_idP, frameP, rx_lcid, module_idP, mac_len, crnti);
|
||||
if (UE_idx->CellGroup) {
|
||||
LOG_D(NR_MAC, "Frame %d : ULSCH -> UL-DCCH %d (gNB %ld, %d bytes), rnti: 0x%04x \n", frameP, rx_lcid, module_idP, mac_len, crnti);
|
||||
mac_rlc_data_ind(module_idP,
|
||||
crnti,
|
||||
module_idP,
|
||||
@@ -406,7 +406,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
1,
|
||||
NULL);
|
||||
} else {
|
||||
AssertFatal(1==0,"[UE %d] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE_id,frameP,slot,rx_lcid);
|
||||
AssertFatal(1==0,"[UE %04x] Frame/Slot %d.%d : Received LCID %d which is not configured, dropping packet\n",UE->rnti,frameP,slot,rx_lcid);
|
||||
}
|
||||
break;
|
||||
case UL_SCH_LCID_SRB3:
|
||||
@@ -444,7 +444,7 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
frameP,
|
||||
0,
|
||||
0,
|
||||
UE_info->rnti[UE_id],
|
||||
UE->rnti,
|
||||
CCCH,
|
||||
pduP + mac_subheader_len,
|
||||
mac_len,
|
||||
@@ -456,18 +456,19 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
|
||||
return 0;
|
||||
|
||||
LOG_D(NR_MAC, "[UE %x] %d.%d: ULSCH -> UL-%s %d (gNB %d, %d bytes)\n",
|
||||
UE_info->rnti[UE_id],
|
||||
|
||||
LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n",
|
||||
UE->rnti,
|
||||
frameP,
|
||||
slot,
|
||||
rx_lcid<4?"DCCH":"DTCH",
|
||||
rx_lcid,
|
||||
module_idP,
|
||||
mac_len);
|
||||
UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_len;
|
||||
UE->mac_stats.lc_bytes_rx[rx_lcid] += mac_len;
|
||||
|
||||
mac_rlc_data_ind(module_idP,
|
||||
UE_info->rnti[UE_id],
|
||||
UE->rnti,
|
||||
module_idP,
|
||||
frameP,
|
||||
ENB_FLAG_YES,
|
||||
@@ -518,15 +519,14 @@ int nr_process_mac_pdu(module_id_t module_idP,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid)
|
||||
void abort_nr_ul_harq( NR_UE_info_t* UE, int8_t harq_pid)
|
||||
{
|
||||
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];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
|
||||
|
||||
harq->ndi ^= 1;
|
||||
harq->round = 0;
|
||||
UE_info->mac_stats[UE_id].ulsch_errors++;
|
||||
UE->mac_stats.ulsch_errors++;
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
|
||||
|
||||
/* the transmission failed: the UE won't send the data we expected initially,
|
||||
@@ -542,11 +542,11 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
sub_frame_t slot,
|
||||
const nfapi_nr_crc_t *crc_pdu)
|
||||
{
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[mod_id];
|
||||
int UE_id = find_nr_UE_id(mod_id, crc_pdu->rnti);
|
||||
if (UE_id < 0) {
|
||||
NR_UE_info_t* UE = find_nr_UE(&RC.nrmac[mod_id]->UE_info, crc_pdu->rnti);
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
|
||||
for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
||||
NR_RA_t *ra = &RC.nrmac[mod_id]->common_channels[CC_idP].ra[i];
|
||||
if (ra->state >= WAIT_Msg3 &&
|
||||
ra->rnti == crc_pdu->rnti)
|
||||
return;
|
||||
@@ -554,8 +554,7 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
LOG_E(NR_MAC, "%s(): unknown RNTI 0x%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];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
|
||||
LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid);
|
||||
while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
|
||||
@@ -569,8 +568,9 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
|
||||
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
|
||||
sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
|
||||
if(sched_ctrl->ul_harq_processes[harq_pid].round >= gNB_mac->harq_round_max - 1) {
|
||||
abort_nr_ul_harq(mod_id, UE_id, harq_pid);
|
||||
|
||||
if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
||||
abort_nr_ul_harq(UE, harq_pid);
|
||||
} else {
|
||||
sched_ctrl->ul_harq_processes[harq_pid].round++;
|
||||
add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
|
||||
@@ -590,8 +590,8 @@ void handle_nr_ul_harq(const int CC_idP,
|
||||
harq_pid,
|
||||
crc_pdu->rnti);
|
||||
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
|
||||
} else if (harq->round >= gNB_mac->harq_round_max - 1) {
|
||||
abort_nr_ul_harq(mod_id, UE_id, harq_pid);
|
||||
} else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) {
|
||||
abort_nr_ul_harq(UE, harq_pid);
|
||||
LOG_D(NR_MAC,
|
||||
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
|
||||
crc_pdu->rnti,
|
||||
@@ -621,15 +621,15 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
const uint16_t rssi){
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[gnb_mod_idP];
|
||||
NR_UE_info_t *UE_info = &gNB_mac->UE_info;
|
||||
|
||||
const int current_rnti = rntiP;
|
||||
const int UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
|
||||
LOG_D(NR_MAC, "rx_sdu for rnti %04x\n", current_rnti);
|
||||
const int target_snrx10 = gNB_mac->pusch_target_snrx10;
|
||||
const int pusch_failure_thres = gNB_mac->pusch_failure_thres;
|
||||
|
||||
if (UE_id != -1) {
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
|
||||
|
||||
NR_UE_info_t* UE = find_nr_UE(&gNB_mac->UE_info, current_rnti);
|
||||
if (UE) {
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||
const int8_t harq_pid = UE_scheduling_control->feedback_ul_harq.head;
|
||||
|
||||
if (sduP)
|
||||
@@ -637,15 +637,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(harq_pid),
|
||||
T_BUFFER(sduP, sdu_lenP));
|
||||
|
||||
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
|
||||
LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d TA %d sduP %p, rssi %d\n",
|
||||
UE->mac_stats.ulsch_total_bytes_rx += sdu_lenP;
|
||||
LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %04x) ul_cqi %d TA %d sduP %p, rssi %d\n",
|
||||
gnb_mod_idP,
|
||||
harq_pid,
|
||||
CC_idP,
|
||||
frameP,
|
||||
slotP,
|
||||
current_rnti,
|
||||
UE_id,
|
||||
ul_cqi,
|
||||
timing_advance,
|
||||
sduP,
|
||||
@@ -658,11 +657,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
UE_scheduling_control->raw_rssi = rssi;
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d(SNRx10 %d) and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->pusch_snrx10,UE_scheduling_control->ta_update);
|
||||
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
}
|
||||
else{
|
||||
LOG_D(NR_MAC,"[UE %d] Detected DTX : increasing UE TX power\n",UE_id);
|
||||
LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti);
|
||||
UE_scheduling_control->tpc0 = 1;
|
||||
|
||||
}
|
||||
|
||||
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
|
||||
@@ -680,13 +681,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
if (sduP != NULL){
|
||||
LOG_D(NR_MAC, "Received PDU at MAC gNB \n");
|
||||
|
||||
UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt = 0;
|
||||
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0;
|
||||
const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
|
||||
UE_scheduling_control->sched_ul_bytes -= tb_size;
|
||||
if (UE_scheduling_control->sched_ul_bytes < 0)
|
||||
UE_scheduling_control->sched_ul_bytes = 0;
|
||||
|
||||
nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP);
|
||||
nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP);
|
||||
}
|
||||
else {
|
||||
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
|
||||
@@ -698,13 +699,15 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
UE_scheduling_control->sched_ul_bytes = 0;
|
||||
}
|
||||
if (ul_cqi <= 128) {
|
||||
UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt++;
|
||||
UE_info->mac_stats[UE_id].ulsch_DTX++;
|
||||
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt++;
|
||||
UE->mac_stats.ulsch_DTX++;
|
||||
}
|
||||
if (!get_softmodem_params()->phy_test && UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
|
||||
LOG_W(NR_MAC,"%d.%d Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
|
||||
frameP,slotP,UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt);
|
||||
UE_info->UE_sched_ctrl[UE_id].ul_failure = 1;
|
||||
|
||||
if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) {
|
||||
LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n",
|
||||
UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt);
|
||||
UE->UE_sched_ctrl.ul_failure = 1;
|
||||
|
||||
nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP);
|
||||
}
|
||||
}
|
||||
@@ -725,7 +728,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
|
||||
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
|
||||
T_BUFFER(sduP, sdu_lenP));
|
||||
|
||||
|
||||
/* we don't know this UE (yet). Check whether there is a ongoing RA (Msg 3)
|
||||
* and check the corresponding UE's RNTI match, in which case we activate
|
||||
* it. */
|
||||
@@ -733,7 +736,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
|
||||
if (ra->state != WAIT_Msg3)
|
||||
continue;
|
||||
|
||||
|
||||
if(no_sig) {
|
||||
LOG_D(NR_MAC, "Random Access %i failed at state %i (no signal)\n", i, ra->state);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
@@ -756,20 +759,20 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
continue;
|
||||
}
|
||||
|
||||
int UE_id=-1;
|
||||
|
||||
UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->CellGroup);
|
||||
if (UE_id<0) {
|
||||
LOG_D(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state,ra->rnti,current_rnti);
|
||||
NR_UE_info_t* UE = add_new_nr_ue(gNB_mac, ra->rnti, ra->CellGroup);
|
||||
if (!UE) {
|
||||
LOG_W(NR_MAC, "Random Access %i discarded at state %i (TC_RNTI %04x RNTI %04x): max number of users achieved!\n", i, ra->state,ra->rnti,current_rnti);
|
||||
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
return;
|
||||
}
|
||||
|
||||
UE_info->UE_beam_index[UE_id] = ra->beam_id;
|
||||
UE->UE_beam_index = ra->beam_id;
|
||||
|
||||
// re-initialize ta update variables after RA procedure completion
|
||||
UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
|
||||
UE->UE_sched_ctrl.ta_frame = frameP;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"reset RA state information for RA-RNTI 0x%04x/index %d\n",
|
||||
@@ -778,28 +781,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
|
||||
LOG_I(NR_MAC,
|
||||
"[gNB %d][RAPROC] PUSCH with TC_RNTI 0x%04x received correctly, "
|
||||
"adding UE MAC Context UE_id %d/RNTI 0x%04x\n",
|
||||
"adding UE MAC Context RNTI 0x%04x\n",
|
||||
gnb_mod_idP,
|
||||
current_rnti,
|
||||
UE_id,
|
||||
ra->rnti);
|
||||
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *UE_scheduling_control = &UE->UE_sched_ctrl;
|
||||
|
||||
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
|
||||
if (timing_advance != 0xffff)
|
||||
UE_scheduling_control->ta_update = timing_advance;
|
||||
UE_scheduling_control->raw_rssi = rssi;
|
||||
UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
|
||||
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n",UE->rnti,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
|
||||
if(ra->cfra) {
|
||||
|
||||
LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
|
||||
LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti);
|
||||
nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
UE_info->active[UE_id] = true;
|
||||
|
||||
process_CellGroup(ra->CellGroup, UE_scheduling_control);
|
||||
process_CellGroup(ra->CellGroup, UE_scheduling_control, NULL, NULL);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -814,25 +814,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
// First byte corresponds to R/LCID MAC sub-header
|
||||
memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
|
||||
|
||||
if (nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP) == 0) {
|
||||
if (nr_process_mac_pdu(gnb_mod_idP, UE, CC_idP, frameP, slotP, sduP, sdu_lenP) == 0) {
|
||||
ra->state = Msg4;
|
||||
ra->Msg4_frame = (frameP + 2) % 1024;
|
||||
ra->Msg4_slot = 1;
|
||||
|
||||
if (ra->msg3_dcch_dtch) {
|
||||
// Check if the UE identified by C-RNTI still exists at the gNB
|
||||
int UE_id_C = find_nr_UE_id(gnb_mod_idP, ra->crnti);
|
||||
if (UE_id_C < 0) {
|
||||
NR_UE_info_t * UE_C = find_nr_UE(&gNB_mac->UE_info, ra->crnti);
|
||||
if (!UE_C) {
|
||||
// The UE identified by C-RNTI no longer exists at the gNB
|
||||
// Let's abort the current RA, so the UE will trigger a new RA later but using RRCSetupRequest instead. A better solution may be implemented
|
||||
mac_remove_nr_ue(gnb_mod_idP, ra->rnti);
|
||||
mac_remove_nr_ue(gNB_mac, ra->rnti);
|
||||
nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
|
||||
return;
|
||||
} else {
|
||||
// The UE identified by C-RNTI still exists at the gNB
|
||||
// Reset uplink failure flags/counters/timers at MAC and at RRC so gNB will resume again scheduling resources for this UE
|
||||
UE_info->UE_sched_ctrl[UE_id_C].pusch_consecutive_dtx_cnt = 0;
|
||||
UE_info->UE_sched_ctrl[UE_id_C].ul_failure = 0;
|
||||
UE_C->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0;
|
||||
UE_C->UE_sched_ctrl.ul_failure = 0;
|
||||
nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->crnti);
|
||||
}
|
||||
}
|
||||
@@ -871,7 +871,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i);
|
||||
|
||||
ra->msg3_round++;
|
||||
ra->state = Msg3_retransmission;
|
||||
}
|
||||
@@ -903,19 +905,20 @@ long get_K2(NR_ServingCellConfigCommon_t *scc,
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t frame, sub_frame_t slot)
|
||||
static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
|
||||
int CC_id, NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
|
||||
{
|
||||
const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels->ServingCellConfigCommon;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
const int now = frame * n + slot;
|
||||
|
||||
const struct gNB_MAC_INST_s *nrmac = RC.nrmac[mod_id];
|
||||
const NR_UE_sched_ctrl_t *sched_ctrl = &nrmac->UE_info.UE_sched_ctrl[UE_id];
|
||||
|
||||
const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl;
|
||||
|
||||
|
||||
const NR_TDD_UL_DL_Pattern_t *tdd =
|
||||
scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
|
||||
int num_slots_per_period;
|
||||
int last_ul_slot,last_ul_sched;
|
||||
int last_ul_slot;
|
||||
int tdd_period_len[8] = {500,625,1000,1250,2000,2500,5000,10000};
|
||||
if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
|
||||
num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000;
|
||||
@@ -926,14 +929,14 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
|
||||
last_ul_slot = sched_ctrl->last_ul_slot;
|
||||
}
|
||||
|
||||
last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
|
||||
const int last_ul_sched = sched_ctrl->last_ul_frame * n + last_ul_slot;
|
||||
const int diff = (now - last_ul_sched + 1024 * n) % (1024 * n);
|
||||
/* UE is to be scheduled if
|
||||
* (1) we think the UE has more bytes awaiting than what we scheduled
|
||||
* (2) there is a scheduling request
|
||||
* (3) or we did not schedule it in more than 10 frames */
|
||||
const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes;
|
||||
const bool high_inactivity = diff >= (nrmac->ulsch_max_frame_inactivity>0 ? (nrmac->ulsch_max_frame_inactivity * n) : num_slots_per_period);
|
||||
const bool high_inactivity = diff >= (ulsch_max_frame_inactivity > 0 ? ulsch_max_frame_inactivity * n : num_slots_per_period);
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d UL inactivity %d slots has_data %d SR %d\n",
|
||||
frame,
|
||||
@@ -944,34 +947,26 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t
|
||||
return has_data || sched_ctrl->SR || high_inactivity;
|
||||
}
|
||||
|
||||
int next_list_entry_looped(NR_list_t *list, int UE_id)
|
||||
{
|
||||
if (UE_id < 0)
|
||||
return list->head;
|
||||
return list->next[UE_id] < 0 ? list->head : list->next[UE_id];
|
||||
}
|
||||
|
||||
bool allocate_ul_retransmission(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
uint16_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
int UE_id,
|
||||
int harq_pid)
|
||||
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
uint16_t *rballoc_mask,
|
||||
int *n_rb_sched,
|
||||
NR_UE_info_t* UE,
|
||||
int harq_pid,
|
||||
const NR_SIB1_t *sib1,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const int tda)
|
||||
{
|
||||
const int CC_id = 0;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
(NR_ServingCellConfigCommon_t *)scc,
|
||||
sib1);
|
||||
@@ -980,7 +975,6 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2;
|
||||
const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda);
|
||||
LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, tbs %d\n",num_dmrs_cdm_grps_no_data, retInfo->tb_size);
|
||||
if (tda == retInfo->time_domain_allocation) {
|
||||
@@ -1008,7 +1002,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap)
|
||||
rbStart++;
|
||||
if (rbStart + retInfo->rbSize > bwpSize) {
|
||||
LOG_W(NR_MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE_id, UE_info->rnti[UE_id], rbStart, retInfo->rbSize, bwpSize);
|
||||
LOG_W(NR_MAC, "cannot allocate retransmission of RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE->rnti, rbStart, retInfo->rbSize, bwpSize);
|
||||
return false;
|
||||
}
|
||||
LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
|
||||
@@ -1058,7 +1052,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
@@ -1068,7 +1062,7 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
int CCEIndex = find_pdcch_candidate(nrmac,
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
@@ -1077,12 +1071,12 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE->rnti);
|
||||
return false;
|
||||
}
|
||||
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
fill_pdcch_vrb_map(RC.nrmac[module_id],
|
||||
fill_pdcch_vrb_map(nrmac,
|
||||
CC_id,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
CCEIndex,
|
||||
@@ -1098,11 +1092,10 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
|
||||
"%4d.%2d Allocate UL retransmission RNTI %04x sched %4d.%2d (%d RBs)\n",
|
||||
frame,
|
||||
slot,
|
||||
UE_id,
|
||||
UE_info->rnti[UE_id],
|
||||
UE->rnti,
|
||||
sched_pusch->frame,
|
||||
sched_pusch->slot,
|
||||
sched_pusch->rbSize);
|
||||
@@ -1129,12 +1122,20 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static
|
||||
}
|
||||
}
|
||||
|
||||
float ul_thr_ue[MAX_MOBILES_PER_GNB];
|
||||
uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
|
||||
typedef struct UEsched_s {
|
||||
float coef;
|
||||
NR_UE_info_t * UE;
|
||||
} UEsched_t;
|
||||
|
||||
static int comparator(const void *p, const void *q) {
|
||||
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
|
||||
}
|
||||
|
||||
void pf_ul(module_id_t module_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot,
|
||||
NR_list_t *UE_list,
|
||||
NR_UE_info_t *UE_list[],
|
||||
int max_num_ue,
|
||||
int n_rb_sched,
|
||||
uint16_t *rballoc_mask) {
|
||||
@@ -1142,28 +1143,29 @@ void pf_ul(module_id_t module_id,
|
||||
const int CC_id = 0;
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
|
||||
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &nrmac->UE_info;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
const int min_rb = nrmac->min_grant_prb;
|
||||
float coeff_ue[MAX_MOBILES_PER_GNB];
|
||||
|
||||
const int min_rb = 5;
|
||||
// UEs that could be scheduled
|
||||
int ue_array[MAX_MOBILES_PER_GNB];
|
||||
NR_list_t UE_sched = { .head = -1, .next = ue_array, .tail = -1, .len = MAX_MOBILES_PER_GNB };
|
||||
UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0};
|
||||
int remainUEs=max_num_ue;
|
||||
int curUE=0;
|
||||
|
||||
/* Loop UE_list to calculate throughput and coeff */
|
||||
for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
|
||||
UEs_iterator(UE_list, UE) {
|
||||
|
||||
if (UE_info->Msg4_ACKed[UE_id] != true) continue;
|
||||
if (UE->Msg4_ACKed != true)
|
||||
continue;
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %d\n",UE_id);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti);
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
|
||||
NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
|
||||
scc,
|
||||
sib1);
|
||||
|
||||
int rbStart = 0; // wrt BWP start
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
@@ -1174,70 +1176,74 @@ void pf_ul(module_id_t module_id,
|
||||
|
||||
/* Calculate throughput */
|
||||
const float a = 0.0005f; // corresponds to 200ms window
|
||||
const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes;
|
||||
ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b;
|
||||
const uint32_t b = UE->mac_stats.ulsch_current_bytes;
|
||||
UE->ul_thr_ue = (1 - a) * UE->ul_thr_ue + a * b;
|
||||
|
||||
/* Check if retransmission is necessary */
|
||||
sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
|
||||
LOG_D(NR_MAC,"pf_ul: UE %d harq_pid %d\n",UE_id,sched_pusch->ul_harq_pid);
|
||||
LOG_D(NR_MAC,"pf_ul: UE %04x harq_pid %d\n",UE->rnti,sched_pusch->ul_harq_pid);
|
||||
if (sched_pusch->ul_harq_pid >= 0) {
|
||||
/* Allocate retransmission*/
|
||||
bool r = allocate_ul_retransmission(
|
||||
module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid);
|
||||
const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
bool r = allocate_ul_retransmission(nrmac, frame, slot, rballoc_mask, &n_rb_sched, UE, sched_pusch->ul_harq_pid, sib1, scc, tda);
|
||||
if (!r) {
|
||||
LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE->rnti);
|
||||
continue;
|
||||
}
|
||||
else LOG_D(NR_MAC,"%4d.%2d UL Retransmission UE RNTI %04x to be allocated, max_num_ue %d\n",frame,slot,UE_info->rnti[UE_id],max_num_ue);
|
||||
else LOG_D(NR_MAC,"%4d.%2d UL Retransmission UE RNTI %04x to be allocated, max_num_ue %d\n",frame,slot,UE->rnti,max_num_ue);
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
if (max_num_ue < 0)
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
remainUEs--;
|
||||
|
||||
if (remainUEs == 0)
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
|
||||
/* preprocessor computed sched_frame/sched_slot */
|
||||
const bool do_sched = nr_UE_is_to_be_scheduled(module_id, 0, UE_id, sched_pusch->frame, sched_pusch->slot);
|
||||
const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity);
|
||||
|
||||
LOG_D(NR_MAC,"pf_ul: do_sched UE %d => %s\n",UE_id,do_sched ? "yes" : "no");
|
||||
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) {
|
||||
LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no");
|
||||
if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled
|
||||
* based on data to transmit) */
|
||||
if (B == 0 && do_sched) {
|
||||
/* if no data, pre-allocate 5RB */
|
||||
/* Find a free CCE */
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE->rnti);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
find_aggregation_candidates(&sched_ctrl->aggregation_level,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
CC_id,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
continue;
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti);
|
||||
continue;
|
||||
}
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
if (max_num_ue < 0)
|
||||
return;
|
||||
remainUEs--;
|
||||
|
||||
if (remainUEs == 0)
|
||||
// we have filled all with mandatory retransmissions
|
||||
// no need to schedule new transmissions
|
||||
return;
|
||||
|
||||
/* Save PUSCH field */
|
||||
/* we want to avoid a lengthy deduction of DMRS and other parameters in
|
||||
@@ -1264,8 +1270,8 @@ void pf_ul(module_id_t module_id,
|
||||
while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap)
|
||||
rbStart++;
|
||||
if (rbStart + min_rb >= bwpSize) {
|
||||
LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
|
||||
UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize);
|
||||
LOG_W(NR_MAC, "cannot allocate continuous UL data for RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
|
||||
UE->rnti,rbStart,min_rb,bwpSize);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1289,7 +1295,7 @@ void pf_ul(module_id_t module_id,
|
||||
0, // nb_rb_oh
|
||||
0,
|
||||
1 /* NrOfLayers */)
|
||||
>> 3;
|
||||
>> 3;
|
||||
|
||||
/* Mark the corresponding RBs as used */
|
||||
n_rb_sched -= sched_pusch->rbSize;
|
||||
@@ -1300,41 +1306,28 @@ void pf_ul(module_id_t module_id,
|
||||
}
|
||||
|
||||
/* Create UE_sched for UEs eligibale for new data transmission*/
|
||||
add_tail_nr_list(&UE_sched, UE_id);
|
||||
|
||||
/* Calculate coefficient*/
|
||||
sched_pusch->mcs = nrmac->min_grant_mcs;
|
||||
const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs];
|
||||
coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id];
|
||||
LOG_D(NR_MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
|
||||
b, UE_id, ul_thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
|
||||
float coeff_ue = (float) tbs / UE->ul_thr_ue;
|
||||
LOG_D(NR_MAC,"rnti %04x b %d, ul_thr_ue %f, tbs %d, coeff_ue %f\n",
|
||||
UE->rnti, b, UE->ul_thr_ue, tbs, UE->coeff_ue);
|
||||
UE_sched[curUE].coef=coeff_ue;
|
||||
UE_sched[curUE].UE=UE;
|
||||
curUE++;
|
||||
}
|
||||
|
||||
|
||||
qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
|
||||
UEsched_t *iterator=UE_sched;
|
||||
|
||||
const int min_rbSize = 5;
|
||||
/* Loop UE_sched to find max coeff and allocate transmission */
|
||||
while (UE_sched.head >= 0 && max_num_ue> 0 && n_rb_sched >= min_rbSize) {
|
||||
/* Find max coeff */
|
||||
int *max = &UE_sched.head; /* Find max coeff: assume head is max */
|
||||
int *p = &UE_sched.next[*max];
|
||||
while (*p >= 0) {
|
||||
/* Find max coeff: if the current one has larger coeff, save for later */
|
||||
if (coeff_ue[*p] > coeff_ue[*max])
|
||||
max = p;
|
||||
p = &UE_sched.next[*p];
|
||||
}
|
||||
/* Find max coeff: remove the max one: do not use remove_nr_list() since it
|
||||
* goes through the whole list every time. Note that UE_sched.tail might
|
||||
* not be set correctly anymore */
|
||||
const int UE_id = *max;
|
||||
p = &UE_sched.next[*max];
|
||||
*max = UE_sched.next[*max];
|
||||
*p = -1;
|
||||
while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) {
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl;
|
||||
|
||||
const int cid = sched_ctrl->coreset->controlResourceSetId;
|
||||
const uint16_t Y = get_Y(cid%3, slot, UE_info->rnti[UE_id]);
|
||||
const uint16_t Y = get_Y(cid%3, slot, iterator->UE->rnti);
|
||||
uint8_t nr_of_candidates;
|
||||
for (int i=0; i<5; i++) {
|
||||
// for now taking the lowest value among the available aggregation levels
|
||||
@@ -1342,7 +1335,8 @@ void pf_ul(module_id_t module_id,
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,
|
||||
1<<i);
|
||||
if(nr_of_candidates>0) break;
|
||||
if(nr_of_candidates>0)
|
||||
break;
|
||||
}
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
CC_id,
|
||||
@@ -1352,16 +1346,12 @@ void pf_ul(module_id_t module_id,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
if (CCEIndex<0) {
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
|
||||
LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x\n", frame, slot, iterator->UE->rnti);
|
||||
continue;
|
||||
}
|
||||
else LOG_D(NR_MAC, "%4d.%2d free CCE for UL DCI UE %04x\n",frame,slot, UE_info->rnti[UE_id]);
|
||||
else LOG_D(NR_MAC, "%4d.%2d free CCE for UL DCI UE %04x\n",frame,slot, iterator->UE->rnti);
|
||||
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
max_num_ue--;
|
||||
AssertFatal(max_num_ue >= 0, "Illegal max_num_ue %d\n", max_num_ue);
|
||||
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *cg = iterator->UE->CellGroup;
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated
|
||||
&& cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
@@ -1405,11 +1395,12 @@ void pf_ul(module_id_t module_id,
|
||||
max_rbSize++;
|
||||
|
||||
if (rbStart + min_rb >= bwpSize) {
|
||||
LOG_W(NR_MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n",
|
||||
UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize);
|
||||
LOG_W(NR_MAC, "cannot allocate UL data for RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d)\n",
|
||||
iterator->UE->rnti,rbStart,min_rb,bwpSize);
|
||||
return;
|
||||
}
|
||||
else LOG_D(NR_MAC,"allocating UL data for UE %d/RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d\n",UE_id, UE_info->rnti[UE_id],rbStart,min_rb,bwpSize);
|
||||
else
|
||||
LOG_D(NR_MAC,"allocating UL data for RNTI %04x (rbStsart %d, min_rb %d, bwpSize %d)\n", iterator->UE->rnti,rbStart,min_rb,bwpSize);
|
||||
|
||||
|
||||
/* Calculate the current scheduling bytes and the necessary RBs */
|
||||
@@ -1443,7 +1434,11 @@ void pf_ul(module_id_t module_id,
|
||||
|
||||
n_rb_sched -= sched_pusch->rbSize;
|
||||
for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
|
||||
|
||||
rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap;
|
||||
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
|
||||
remainUEs--;
|
||||
iterator++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1460,9 +1455,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing :
|
||||
scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing;
|
||||
|
||||
NR_UE_info_t *UE_info = &nr_mac->UE_info;
|
||||
|
||||
if (UE_info->num_UEs == 0)
|
||||
if (nr_mac->UE_info.list[0] == NULL)
|
||||
// no UEs
|
||||
return false;
|
||||
|
||||
const int CC_id = 0;
|
||||
@@ -1471,8 +1465,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
* have the same K2 (we don't support multiple/different K2s via different
|
||||
* TDAs yet). If the TDA is negative, it means that there is no UL slot to
|
||||
* schedule now (slot + k2 is not UL slot) */
|
||||
int UE_id = UE_info->list.head;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &nr_mac->UE_info.list[0]->UE_sched_ctrl;
|
||||
const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (tda < 0)
|
||||
return false;
|
||||
@@ -1496,9 +1489,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
return false;
|
||||
|
||||
// Avoid slots with the SRS
|
||||
const NR_list_t *UE_list = &UE_info->list;
|
||||
for (int UE_idx = UE_list->head; UE_idx >= 0; UE_idx = UE_list->next[UE_idx]) {
|
||||
NR_sched_srs_t sched_srs = UE_info->UE_sched_ctrl[UE_idx].sched_srs;
|
||||
UEs_iterator(nr_mac->UE_info.list, UE) {
|
||||
NR_sched_srs_t sched_srs = UE->UE_sched_ctrl.sched_srs;
|
||||
if(sched_srs.srs_scheduled && sched_srs.frame==sched_frame && sched_srs.slot==sched_slot) {
|
||||
return false;
|
||||
}
|
||||
@@ -1506,10 +1498,11 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
UEs_iterator(nr_mac->UE_info.list, UE2) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl;
|
||||
AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu),
|
||||
"Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE_id);
|
||||
"Different K2, %d(UE%d) != %ld(UE%04x)\n",
|
||||
K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti);
|
||||
sched_ctrl->sched_pusch.slot = sched_slot;
|
||||
sched_ctrl->sched_pusch.frame = sched_frame;
|
||||
}
|
||||
@@ -1569,7 +1562,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t
|
||||
pf_ul(module_id,
|
||||
frame,
|
||||
slot,
|
||||
&UE_info->list,
|
||||
nr_mac->UE_info.list,
|
||||
2,
|
||||
len,
|
||||
rballoc_mask);
|
||||
@@ -1630,29 +1623,28 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
|
||||
const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
|
||||
const NR_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];
|
||||
UEs_iterator( UE_info->list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue;
|
||||
|
||||
NR_CellGroupConfig_t *cg = UE_info->CellGroup[UE_id];
|
||||
NR_CellGroupConfig_t *cg = UE->CellGroup;
|
||||
|
||||
NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated &&
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig ?
|
||||
cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL;
|
||||
|
||||
UE_info->mac_stats[UE_id].ulsch_current_bytes = 0;
|
||||
UE->mac_stats.ulsch_current_bytes = 0;
|
||||
|
||||
/* 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;
|
||||
LOG_D(NR_MAC,"UE %x : sched_pusch->rbSize %d\n",UE_info->rnti[UE_id],sched_pusch->rbSize);
|
||||
LOG_D(NR_MAC,"UE %04x : sched_pusch->rbSize %d\n",UE->rnti,sched_pusch->rbSize);
|
||||
if (sched_pusch->rbSize <= 0)
|
||||
continue;
|
||||
|
||||
uint16_t rnti = UE_info->rnti[UE_id];
|
||||
uint16_t rnti = UE->rnti;
|
||||
sched_ctrl->SR = false;
|
||||
|
||||
int8_t harq_id = sched_pusch->ul_harq_pid;
|
||||
@@ -1660,8 +1652,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
/* PP has not selected a specific HARQ Process, get a new one */
|
||||
harq_id = sched_ctrl->available_ul_harq.head;
|
||||
AssertFatal(harq_id >= 0,
|
||||
"no free HARQ process available for UE %d\n",
|
||||
UE_id);
|
||||
"no free HARQ process available for UE %04x\n",
|
||||
UE->rnti);
|
||||
remove_front_nr_list(&sched_ctrl->available_ul_harq);
|
||||
sched_pusch->ul_harq_pid = harq_id;
|
||||
} else {
|
||||
@@ -1688,9 +1680,9 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
|
||||
/* Statistics */
|
||||
AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
|
||||
UE->mac_stats.ulsch_rounds[cur_harq->round]++;
|
||||
if (cur_harq->round == 0) {
|
||||
UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
/* Save information on MCS, TBS etc for the current initial transmission
|
||||
* so we have access to it when retransmitting */
|
||||
cur_harq->sched_pusch = *sched_pusch;
|
||||
@@ -1710,7 +1702,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
cur_harq->round,
|
||||
cur_harq->ndi);
|
||||
}
|
||||
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
|
||||
UE->mac_stats.ulsch_current_bytes = sched_pusch->tb_size;
|
||||
sched_ctrl->last_ul_frame = sched_pusch->frame;
|
||||
sched_ctrl->last_ul_slot = sched_pusch->slot;
|
||||
|
||||
@@ -1890,7 +1882,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
pdcch_pdu_coreset[coresetid] = pdcch_pdu;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC,"Configuring ULDCI/PDCCH in %d.%d at CCE %d, rnti %x\n", frame,slot,sched_ctrl->cce_index,rnti);
|
||||
LOG_D(NR_MAC,"Configuring ULDCI/PDCCH in %d.%d at CCE %d, rnti %04x\n", frame,slot,sched_ctrl->cce_index,rnti);
|
||||
|
||||
/* Fill PDCCH DL DCI PDU */
|
||||
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu->dci_pdu[pdcch_pdu->numDlDci];
|
||||
@@ -1928,7 +1920,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
|
||||
&uldci_payload,
|
||||
ps->dci_format,
|
||||
ps->time_domain_allocation,
|
||||
UE_info->UE_sched_ctrl[UE_id].tpc0,
|
||||
UE->UE_sched_ctrl.tpc0,
|
||||
n_ubwp,
|
||||
bwpid);
|
||||
fill_dci_pdu_rel15(scc,
|
||||
|
||||
@@ -38,8 +38,6 @@ void set_cset_offset(uint16_t);
|
||||
|
||||
void mac_top_init_gNB(void);
|
||||
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts,
|
||||
@@ -62,7 +60,9 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
NR_BCCH_DL_SCH_Message_t *sib1,
|
||||
int add_ue,
|
||||
uint32_t rnti,
|
||||
NR_CellGroupConfig_t *CellGroup);
|
||||
NR_CellGroupConfig_t *CellGroup,
|
||||
pdu_session_param_t *pduSession,
|
||||
NR_DRB_ToAddModList_t *DRB_configList);
|
||||
|
||||
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
|
||||
int CC_idP,
|
||||
@@ -199,7 +199,7 @@ void config_uldci(const NR_SIB1_t *sib1,
|
||||
int n_ubwp,
|
||||
int bwp_id);
|
||||
|
||||
void nr_schedule_pucch(int Mod_idP,
|
||||
void nr_schedule_pucch(gNB_MAC_INST* nrmac,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
@@ -214,15 +214,14 @@ void nr_csi_meas_reporting(int Mod_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP);
|
||||
|
||||
int nr_acknack_scheduling(int Mod_idP,
|
||||
int UE_id,
|
||||
int nr_acknack_scheduling( int Mod_idP,
|
||||
NR_UE_info_t * UE,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
int r_pucch,
|
||||
int do_common);
|
||||
|
||||
void get_pdsch_to_harq_feedback(int Mod_idP,
|
||||
int UE_id,
|
||||
void get_pdsch_to_harq_feedback(NR_UE_info_t *,
|
||||
int bwp_id,
|
||||
NR_SearchSpace__searchSpaceType_PR ss_type,
|
||||
int *max_fb_time,
|
||||
@@ -331,7 +330,7 @@ NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(
|
||||
const NR_SIB1_t *sib1);
|
||||
|
||||
/* find coreset within the search space */
|
||||
NR_ControlResourceSet_t *get_coreset(module_id_t module_idP,
|
||||
NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
void *bwp,
|
||||
NR_SearchSpace_t *ss,
|
||||
@@ -395,7 +394,6 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB);
|
||||
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
|
||||
|
||||
/* Functions to manage an NR_list_t */
|
||||
void dump_nr_list(NR_list_t *listP);
|
||||
void create_nr_list(NR_list_t *listP, int len);
|
||||
void resize_nr_list(NR_list_t *list, int new_len);
|
||||
void destroy_nr_list(NR_list_t *list);
|
||||
@@ -405,13 +403,13 @@ void add_tail_nr_list(NR_list_t *listP, int id);
|
||||
void add_front_nr_list(NR_list_t *listP, int id);
|
||||
void remove_front_nr_list(NR_list_t *listP);
|
||||
|
||||
int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP);
|
||||
NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, 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, NR_CellGroupConfig_t *CellGroup);
|
||||
NR_UE_info_t*add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup);
|
||||
|
||||
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
|
||||
void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti);
|
||||
|
||||
void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
|
||||
|
||||
@@ -425,7 +423,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
|
||||
|
||||
int nr_get_default_pucch_res(int pucch_ResourceCommon);
|
||||
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_info, int UE_id, module_id_t Mod_idP);
|
||||
void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE);
|
||||
|
||||
int get_dlscs(nfapi_nr_config_request_t *cfg);
|
||||
|
||||
@@ -513,7 +511,7 @@ int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp);
|
||||
void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp);
|
||||
|
||||
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id);
|
||||
bool find_free_CCE(sub_frame_t slot, NR_UE_info_t *UE);
|
||||
|
||||
bool nr_find_nb_rb(uint16_t Qm,
|
||||
uint16_t R,
|
||||
@@ -526,10 +524,10 @@ bool nr_find_nb_rb(uint16_t Qm,
|
||||
uint32_t *tbs,
|
||||
uint16_t *nb_rb);
|
||||
|
||||
void nr_sr_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP);
|
||||
void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP);
|
||||
|
||||
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp);
|
||||
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl);
|
||||
void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl, pdu_session_param_t *pduSession, NR_DRB_ToAddModList_t *DRB_configList);
|
||||
|
||||
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
|
||||
|
||||
@@ -57,7 +57,7 @@ void *nrmac_stats_thread(void *arg) {
|
||||
AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno));
|
||||
|
||||
while (oai_exit == 0) {
|
||||
dump_mac_stats(gNB,output,MACSTATSSTRLEN,false);
|
||||
dump_mac_stats(gNB,output,MACSTATSSTRLEN,false);
|
||||
fprintf(fd,"%s\n",output);
|
||||
fflush(fd);
|
||||
usleep(200000);
|
||||
@@ -68,40 +68,39 @@ void *nrmac_stats_thread(void *arg) {
|
||||
}
|
||||
|
||||
void clear_mac_stats(gNB_MAC_INST *gNB) {
|
||||
memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t));
|
||||
UEs_iterator(gNB->UE_info.list, UE) {
|
||||
memset(&UE->mac_stats,0,sizeof(UE->mac_stats));
|
||||
}
|
||||
}
|
||||
|
||||
void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp)
|
||||
{
|
||||
NR_UE_info_t *UE_info = &gNB->UE_info;
|
||||
int num = 1;
|
||||
|
||||
int stroff=0;
|
||||
if (UE_info->num_UEs == 0) return;
|
||||
|
||||
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
|
||||
|
||||
const NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
|
||||
pthread_mutex_lock(&gNB->UE_info.mutex);
|
||||
UEs_iterator(gNB->UE_info.list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_mac_stats_t *stats = &UE->mac_stats;
|
||||
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
|
||||
stroff+=sprintf(output+stroff,"UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n",
|
||||
UE_id,
|
||||
UE_info->rnti[UE_id],
|
||||
num++,
|
||||
UE_info->num_UEs,
|
||||
sched_ctrl->ph,
|
||||
sched_ctrl->pcmax,
|
||||
avg_rsrp,
|
||||
stats->num_rsrp_meas);
|
||||
stroff+=sprintf(output+stroff,"UE %d: CQI %d, RI %d, PMI (%d,%d)\n",
|
||||
UE_id,
|
||||
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
||||
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
|
||||
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
|
||||
UE_info->UE_sched_ctrl[UE_id].CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
||||
|
||||
stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
|
||||
UE_id,
|
||||
stroff+=sprintf(output+stroff,"UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n",
|
||||
UE->rnti,
|
||||
num++,
|
||||
sched_ctrl->ph,
|
||||
sched_ctrl->pcmax,
|
||||
avg_rsrp,
|
||||
stats->num_rsrp_meas);
|
||||
stroff+=sprintf(output+stroff,"UE %04x: CQI %d, RI %d, PMI (%d,%d)\n",
|
||||
UE->rnti,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1,
|
||||
UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2);
|
||||
|
||||
stroff+=sprintf(output+stroff,"UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n",
|
||||
UE->rnti,
|
||||
|
||||
stats->dlsch_rounds[0], stats->dlsch_rounds[1],
|
||||
stats->dlsch_rounds[2], stats->dlsch_rounds[3],
|
||||
stats->dlsch_errors,
|
||||
@@ -112,28 +111,29 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
|
||||
stats->num_rsrp_meas = 0;
|
||||
stats->cumul_rsrp = 0;
|
||||
}
|
||||
stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %"PRIu64"\n", UE_id, stats->dlsch_total_bytes);
|
||||
stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n",
|
||||
UE_id,
|
||||
stroff+=sprintf(output+stroff,"UE %04x: dlsch_total_bytes %"PRIu64"\n", UE->rnti, stats->dlsch_total_bytes);
|
||||
stroff+=sprintf(output+stroff,"UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64"\n",
|
||||
UE->rnti,
|
||||
stats->ulsch_rounds[0], stats->ulsch_rounds[1],
|
||||
stats->ulsch_rounds[2], stats->ulsch_rounds[3],
|
||||
stats->ulsch_DTX,
|
||||
stats->ulsch_errors);
|
||||
stroff+=sprintf(output+stroff,
|
||||
"UE %d: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
|
||||
UE_id,
|
||||
"UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n",
|
||||
UE->rnti,
|
||||
stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx);
|
||||
for (int lc_id = 0; lc_id < 63; lc_id++) {
|
||||
if (stats->lc_bytes_tx[lc_id] > 0) {
|
||||
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
|
||||
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]);
|
||||
stroff+=sprintf(output+stroff, "UE %04x: LCID %d: %"PRIu64" bytes TX\n", UE->rnti, lc_id, stats->lc_bytes_tx[lc_id]);
|
||||
LOG_D(NR_MAC, "UE %04x: LCID %d: %"PRIu64" bytes TX\n", UE->rnti, lc_id, stats->lc_bytes_tx[lc_id]);
|
||||
}
|
||||
if (stats->lc_bytes_rx[lc_id] > 0) {
|
||||
stroff+=sprintf(output+stroff, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
|
||||
LOG_D(NR_MAC, "UE %d: LCID %d: %"PRIu64" bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
|
||||
stroff+=sprintf(output+stroff, "UE %04x: LCID %d: %"PRIu64" bytes RX\n", UE->rnti, lc_id, stats->lc_bytes_rx[lc_id]);
|
||||
LOG_D(NR_MAC, "UE %04x: LCID %d: %"PRIu64" bytes RX\n", UE->rnti, lc_id, stats->lc_bytes_rx[lc_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&gNB->UE_info.mutex);
|
||||
print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
|
||||
print_meas(&gNB->schedule_dlsch,"dlsch scheduler",NULL,NULL);
|
||||
print_meas(&gNB->rlc_data_req, "rlc_data_req",NULL,NULL);
|
||||
@@ -144,8 +144,6 @@ void dump_mac_stats(gNB_MAC_INST *gNB, char *output, int strlen, bool reset_rsrp
|
||||
void mac_top_init_gNB(void)
|
||||
{
|
||||
module_id_t i;
|
||||
int list_el;
|
||||
NR_UE_info_t *UE_info;
|
||||
gNB_MAC_INST *nrmac;
|
||||
|
||||
LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst);
|
||||
@@ -179,6 +177,8 @@ void mac_top_init_gNB(void)
|
||||
|
||||
RC.nrmac[i]->first_MIB = true;
|
||||
|
||||
pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL);
|
||||
|
||||
if (get_softmodem_params()->phy_test) {
|
||||
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
|
||||
RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
|
||||
@@ -210,13 +210,7 @@ void mac_top_init_gNB(void)
|
||||
|
||||
nrmac = RC.nrmac[i];
|
||||
nrmac->if_inst = NR_IF_Module_init(i);
|
||||
|
||||
UE_info = &nrmac->UE_info;
|
||||
UE_info->num_UEs = 0;
|
||||
create_nr_list(&UE_info->list, MAX_MOBILES_PER_GNB);
|
||||
for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) {
|
||||
UE_info->active[list_el] = false;
|
||||
}
|
||||
memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info));
|
||||
}
|
||||
|
||||
srand48(0);
|
||||
|
||||
@@ -89,6 +89,7 @@ typedef struct {
|
||||
int len;
|
||||
} NR_list_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
RA_IDLE = 0,
|
||||
Msg2 = 1,
|
||||
@@ -554,6 +555,10 @@ typedef struct NR_UE_ul_harq {
|
||||
NR_sched_pusch_t sched_pusch;
|
||||
} NR_UE_ul_harq_t;
|
||||
|
||||
typedef struct NR_QoS_config {
|
||||
uint64_t fiveQI;
|
||||
} NR_QoS_config_t;
|
||||
|
||||
/*! \brief scheduling control information set through an API */
|
||||
#define MAX_CSI_REPORTS 48
|
||||
typedef struct {
|
||||
@@ -651,6 +656,10 @@ typedef struct {
|
||||
|
||||
/// Timer for RRC processing procedures
|
||||
uint32_t rrc_processing_timer;
|
||||
|
||||
/// Information about the QoS configuration for each LCID
|
||||
NR_QoS_config_t nr_QoS_config[NR_MAX_NUM_LCID];
|
||||
|
||||
} NR_UE_sched_ctrl_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -676,27 +685,37 @@ typedef struct {
|
||||
uint8_t num_rsrp_meas;
|
||||
} NR_mac_stats_t;
|
||||
|
||||
|
||||
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
|
||||
#define MAX_CSI_REPORTCONFIG 48
|
||||
typedef struct {
|
||||
rnti_t rnti;
|
||||
/// 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];
|
||||
NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
|
||||
NR_list_t list;
|
||||
int num_UEs;
|
||||
bool active[MAX_MOBILES_PER_GNB];
|
||||
rnti_t rnti[MAX_MOBILES_PER_GNB];
|
||||
NR_CellGroupConfig_t *CellGroup[MAX_MOBILES_PER_GNB];
|
||||
nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG];
|
||||
NR_UE_sched_ctrl_t UE_sched_ctrl;
|
||||
NR_mac_stats_t mac_stats;
|
||||
NR_CellGroupConfig_t *CellGroup;
|
||||
/// CCE indexing
|
||||
int m[MAX_MOBILES_PER_GNB];
|
||||
int m;
|
||||
// UE selected beam index
|
||||
uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
|
||||
bool Msg4_ACKed[MAX_MOBILES_PER_GNB];
|
||||
|
||||
uint8_t UE_beam_index;
|
||||
bool Msg4_ACKed;
|
||||
NR_gNB_UCI_STATS_t uci_statS;
|
||||
float ul_thr_ue;
|
||||
float dl_thr_ue;
|
||||
float coeff_ue;
|
||||
float dl_coeff_ue;
|
||||
int layers;
|
||||
} NR_UE_info_t;
|
||||
|
||||
typedef struct {
|
||||
/// scheduling control info
|
||||
// last element always NULL
|
||||
pthread_mutex_t mutex;
|
||||
NR_UE_info_t *list[MAX_MOBILES_PER_GNB+1];
|
||||
} NR_UEs_t;
|
||||
|
||||
#define UEs_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++)))
|
||||
|
||||
typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
|
||||
frame_t frame,
|
||||
sub_frame_t slot);
|
||||
@@ -755,7 +774,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
/// NFAPI DL PDU structure
|
||||
nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX];
|
||||
int pdcch_cand[MAX_NUM_CORESET];
|
||||
NR_UE_info_t UE_info;
|
||||
NR_UEs_t UE_info;
|
||||
|
||||
/// UL handle
|
||||
uint32_t ul_handle;
|
||||
|
||||
@@ -372,9 +372,6 @@ static void match_crc_rx_pdu(nfapi_nr_rx_data_indication_t *rx_ind, nfapi_nr_crc
|
||||
|
||||
void NR_UL_indication(NR_UL_IND_t *UL_info) {
|
||||
AssertFatal(UL_info!=NULL,"UL_info is null\n");
|
||||
#ifdef DUMP_FAPI
|
||||
dump_ul(UL_info);
|
||||
#endif
|
||||
module_id_t module_id = UL_info->module_id;
|
||||
int CC_id = UL_info->CC_id;
|
||||
NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id];
|
||||
|
||||
@@ -176,6 +176,8 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
|
||||
rrc->carrier.siblock1,
|
||||
0,
|
||||
0, // WIP hardcoded rnti
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -273,6 +275,8 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
rrc_gNB_ue_context_t *const ue_context_pP,
|
||||
const protocol_ctxt_t *const ctxt_pP ) {
|
||||
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
|
||||
NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL;
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->configuration.ssb_SubcarrierOffset,
|
||||
@@ -285,7 +289,10 @@ void apply_macrlc_config(gNB_RRC_INST *rrc,
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
cgc);
|
||||
cgc,
|
||||
NULL,
|
||||
ue_context_pP->ue_context.DRB_configList2[xid]);
|
||||
|
||||
|
||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
ue_context_pP->ue_context.SRB_configList,
|
||||
@@ -442,6 +449,7 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
|
||||
rrc_gNB_ue_context_t *ue_context_pP = NULL;
|
||||
gNB_RRC_INST *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id];
|
||||
NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon;
|
||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||
|
||||
ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0);
|
||||
|
||||
@@ -473,7 +481,9 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(
|
||||
rrc_instance_p->carrier.siblock1,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
NULL);
|
||||
NULL,
|
||||
NULL,
|
||||
ue_context_pP->ue_context.DRB_configList2[xid]);
|
||||
|
||||
LOG_I(NR_RRC,
|
||||
PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n",
|
||||
@@ -943,7 +953,13 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
|
||||
case 7: //100ms
|
||||
case 8: //300ms
|
||||
case 9: //300ms Video (Buffered Streaming)TCP-based (e.g., www, e-mail, chat, ftp, p2p file sharing, progressive video, etc.)
|
||||
// TODO
|
||||
LOG_D(NR_RRC, "PDU SESSION ID %ld, DRB ID %ld (index %d), QOS flow %d, 5QI %ld \n",
|
||||
DRB_config->cnAssociation->choice.sdap_Config->pdu_Session,
|
||||
DRB_config->drb_Identity,
|
||||
i,
|
||||
qos_flow_index,
|
||||
ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1408,7 +1424,10 @@ rrc_gNB_process_RRCReconfigurationComplete(
|
||||
NULL,
|
||||
0,
|
||||
ue_context_pP->ue_context.rnti,
|
||||
ue_context_pP->ue_context.masterCellGroup);
|
||||
ue_context_pP->ue_context.masterCellGroup,
|
||||
ue_context_pP->ue_context.pduSession,
|
||||
DRB_configList);
|
||||
|
||||
LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti);
|
||||
nr_rrc_rlc_config_asn1_req(ctxt_pP,
|
||||
SRB_configList, // NULL,
|
||||
@@ -1610,7 +1629,7 @@ rrc_gNB_generate_RRCReestablishment(
|
||||
ue_context->Srb0.Tx_buffer.payload_size);
|
||||
#if(0)
|
||||
/* TODO : It may be needed if gNB goes into full stack working. */
|
||||
UE_id = find_nr_UE_id(module_id, rnti);
|
||||
UE = find_nr_UE(module_id, rnti);
|
||||
if (UE_id != -1) {
|
||||
/* Activate reject timer, if RRCComplete not received after 10 frames, reject UE */
|
||||
RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
|
||||
@@ -3451,6 +3470,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
FILE *fd=NULL;//fopen("nrRRCstats.log","w");
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) {
|
||||
ctxt_pP->rnti = ue_context_p->ue_id_rnti;
|
||||
gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!!
|
||||
|
||||
if (fd) {
|
||||
if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) {
|
||||
@@ -3490,7 +3510,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
|
||||
// Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G
|
||||
if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) {
|
||||
mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
|
||||
mac_remove_nr_ue(nrmac, ctxt_pP->rnti);
|
||||
rrc_rlc_remove_ue(ctxt_pP);
|
||||
pdcp_remove_UE(ctxt_pP);
|
||||
|
||||
@@ -3514,7 +3534,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
ue_context_p->ue_context.rnti);
|
||||
ue_context_p->ue_context.ue_release_timer_rrc = 0;
|
||||
|
||||
mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti);
|
||||
mac_remove_nr_ue(nrmac, ctxt_pP->rnti);
|
||||
rrc_rlc_remove_ue(ctxt_pP);
|
||||
pdcp_remove_UE(ctxt_pP);
|
||||
newGtpuDeleteAllTunnels(ctxt_pP->instance, ctxt_pP->rnti);
|
||||
|
||||
@@ -354,7 +354,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
NULL,
|
||||
1, // add_ue flag
|
||||
ue_context_p->ue_id_rnti,
|
||||
ue_context_p->ue_context.secondaryCellGroup);
|
||||
ue_context_p->ue_context.secondaryCellGroup,
|
||||
NULL,
|
||||
NULL);
|
||||
} else {
|
||||
rrc_mac_config_req_gNB(rrc->module_id,
|
||||
rrc->configuration.ssb_SubcarrierOffset,
|
||||
@@ -367,7 +369,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
NULL,
|
||||
1, // add_ue flag
|
||||
ue_context_p->ue_id_rnti,
|
||||
ue_context_p->ue_context.secondaryCellGroup);
|
||||
ue_context_p->ue_context.secondaryCellGroup,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0, rrc->module_id);
|
||||
@@ -421,7 +425,8 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
|
||||
|
||||
rrc_rlc_remove_ue(&ctxt);
|
||||
|
||||
mac_remove_nr_ue(rrc->module_id, rnti);
|
||||
// WHAT A RACE CONDITION
|
||||
mac_remove_nr_ue(RC.nrmac[rrc->module_id], rnti);
|
||||
gtpv1u_enb_delete_tunnel_req_t tmp={0};
|
||||
tmp.rnti=rnti;
|
||||
tmp.from_gnb=1;
|
||||
|
||||
@@ -109,11 +109,14 @@ typedef enum radio_type_e {
|
||||
|
||||
extern int opt_enabled;
|
||||
#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x)
|
||||
#define trace_NRpdu(x...) if (opt_enabled) trace_pdu_implementation(1, x)
|
||||
#define trace_NRpdu(x...) if (opt_enabled) nr_trace_pdu_implementation(1, x)
|
||||
|
||||
void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
|
||||
int oob_event, int oob_event_value);
|
||||
void nr_trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe,
|
||||
int oob_event, int oob_event_value);
|
||||
|
||||
int init_opt(void);
|
||||
|
||||
|
||||
@@ -476,6 +476,14 @@ static void SendFrameNR(guint8 radioType, guint8 direction, guint8 rntiType,
|
||||
extern RAN_CONTEXT_t RC;
|
||||
#include <openair1/PHY/phy_extern_ue.h>
|
||||
/* Remote serveraddress (where Wireshark is running) */
|
||||
void nr_trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
|
||||
int oob_event_value) {
|
||||
trace_pdu_implementation(nr, direction, pdu_buffer, pdu_buffer_size,
|
||||
rnti, rntiType, rnti, sysFrameNumber, subFrameNumber, oob_event,
|
||||
oob_event_value);
|
||||
}
|
||||
|
||||
void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size,
|
||||
int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event,
|
||||
int oob_event_value) {
|
||||
|
||||
Reference in New Issue
Block a user