* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fapi_5g / source / api / fapi2mac / p7 / nr5g_fapi_proc_crc_ind.c
1 /******************************************************************************
2 *
3 *   Copyright (c) 2021 Intel.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 *
17 *******************************************************************************/
18 /**
19  * @file
20  * This file consist of implementation of FAPI CRC.indication message.
21  *
22  **/
23
24 #include "nr5g_mac_phy_api.h"
25 #include "nr5g_fapi_framework.h"
26 #include "nr5g_fapi_fapi2mac_api.h"
27 #include "nr5g_fapi_fapi2mac_p7_proc.h"
28 #include "nr5g_fapi_fapi2mac_p7_pvt_proc.h"
29 #include "nr5g_fapi_snr_conversion.h"
30
31  /** @ingroup group_source_api_p7_fapi2mac_proc
32  *
33  *  @param[in]  p_phy_ctx Pointer to PHY context.
34  *  @param[in]  p_phy_crc_ind Pointer to FAPI CRC.indication message structure.
35  *  
36  *  @return     Returns ::SUCCESS and ::FAILURE.
37  *
38  *  @description
39  *  This message includes CRC PDU.
40  *
41 **/
42 uint8_t nr5g_fapi_crc_indication(
43     bool is_urllc,
44     p_nr5g_fapi_phy_ctx_t p_phy_ctx,
45     p_fapi_api_stored_vendor_queue_elems vendor_extension_elems,
46     PCRCIndicationStruct p_phy_crc_ind)
47 {
48     uint8_t phy_id;
49     fapi_crc_ind_t *p_fapi_crc_ind;
50     p_fapi_api_queue_elem_t p_list_elem;
51     p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
52     nr5g_fapi_stats_t *p_stats;
53
54     if (NULL == p_phy_ctx) {
55         NR5G_FAPI_LOG(ERROR_LOG, ("[CRC.indication] Invalid " "phy context"));
56         return FAILURE;
57     }
58
59     if (NULL == p_phy_crc_ind) {
60         NR5G_FAPI_LOG(ERROR_LOG, ("[NR5G_FAPI [CRC.indication] Invalid Phy "
61                 "CRC indication"));
62         return FAILURE;
63     }
64
65     phy_id = p_phy_crc_ind->sSFN_Slot.nCarrierIdx;
66     p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
67     if (p_phy_instance->phy_id != phy_id) {
68         NR5G_FAPI_LOG(ERROR_LOG, ("[CRC.indication] Invalid " "phy instance"));
69         return FAILURE;
70     }
71
72     p_stats = &p_phy_instance->stats;
73     p_stats->iapi_stats.iapi_crc_ind++;
74
75     p_list_elem =
76         nr5g_fapi_fapi2mac_create_api_list_elem(FAPI_CRC_INDICATION, 1,
77         sizeof(fapi_crc_ind_t));
78
79     if (!p_list_elem) {
80         NR5G_FAPI_LOG(ERROR_LOG, ("[CRC.indication] Unable to create "
81                 "list element. Out of memory!!!"));
82         return FAILURE;
83     }
84
85     p_fapi_crc_ind = (fapi_crc_ind_t *) (p_list_elem + 1);
86     p_fapi_crc_ind->header.msg_id = FAPI_CRC_INDICATION;
87     p_fapi_crc_ind->header.length = (uint16_t) sizeof(fapi_crc_ind_t);
88
89     fapi_vendor_p7_ind_msg_t* p_fapi_vend_p7 =
90         nr5g_fapi_proc_vendor_p7_msg_get(vendor_extension_elems, phy_id);
91     fapi_vendor_ext_snr_t* p_fapi_snr  = p_fapi_vend_p7 ? &p_fapi_vend_p7->crc_snr : NULL;
92     fapi_vendor_ext_crc_ind_t* p_fapi_vend_crc_ind = p_fapi_vend_p7 ? &p_fapi_vend_p7->crc_ind : NULL;
93     
94     if (p_fapi_vend_crc_ind) {
95         p_fapi_vend_crc_ind->carrier_idx = phy_id;
96         p_fapi_vend_crc_ind->sym = p_phy_crc_ind->sSFN_Slot.nSym;
97     }
98
99     if (nr5g_fapi_crc_indication_to_fapi_translation(is_urllc, p_phy_instance,
100             p_phy_crc_ind, p_fapi_crc_ind, p_fapi_snr)) {
101         NR5G_FAPI_LOG(ERROR_LOG, ("[CRC.indication] L1 to FAPI "
102                 "translation failed"));
103         return FAILURE;
104     }
105
106     nr5g_fapi_fapi2mac_add_api_to_list(phy_id, p_list_elem, is_urllc);
107
108     p_stats->fapi_stats.fapi_crc_ind++;
109
110     NR5G_FAPI_LOG(DEBUG_LOG, ("[CRC.indication][%u][%u,%u,%u] is_urllc %u",
111             p_phy_instance->phy_id,
112             p_phy_crc_ind->sSFN_Slot.nSFN, p_phy_crc_ind->sSFN_Slot.nSlot,
113             p_phy_crc_ind->sSFN_Slot.nSym, is_urllc));
114
115     return SUCCESS;
116 }
117
118  /** @ingroup group_source_api_p7_fapi2mac_proc
119  *
120  *  @param[in]  p_phy_instance Pointer to PHY instance.
121  *  @param[in]   p_phy_crc_ind Pointer to IAPI CRC.indication structure.
122  *  @param[out]  p_fapi_crc_ind Pointer to FAPI CRC.indication structure.
123  *  
124  *  @return     Returns ::SUCCESS and ::FAILURE.
125  *
126  *  @description
127  *  This function converts IAPI CRC.indication to FAPI CRC.indication
128  *  structure.
129  *
130 **/
131 uint8_t nr5g_fapi_crc_indication_to_fapi_translation(
132     bool is_urllc,
133     p_nr5g_fapi_phy_instance_t p_phy_instance,
134     PCRCIndicationStruct p_phy_crc_ind,
135     fapi_crc_ind_t * p_fapi_crc_ind,
136     fapi_vendor_ext_snr_t * p_fapi_snr)
137 {
138     uint8_t num_crc, i;
139     uint8_t symbol_no;
140     uint16_t slot_no, frame_no;
141
142     nr5g_fapi_pusch_info_t *p_pusch_info;
143     fapi_crc_ind_info_t *p_fapi_crc_ind_info;
144     nr5g_fapi_ul_slot_info_t *p_ul_slot_info;
145     nr5g_fapi_stats_t *p_stats;
146     ULCRCStruct *p_ul_crc_struct;
147
148     p_stats = &p_phy_instance->stats;
149
150     frame_no = p_fapi_crc_ind->sfn = p_phy_crc_ind->sSFN_Slot.nSFN;
151     slot_no = p_fapi_crc_ind->slot = p_phy_crc_ind->sSFN_Slot.nSlot;
152     symbol_no = p_phy_crc_ind->sSFN_Slot.nSym;
153
154     p_ul_slot_info =
155         nr5g_fapi_get_ul_slot_info(is_urllc, frame_no, slot_no, symbol_no, p_phy_instance);
156
157     if (p_ul_slot_info == NULL) {
158         NR5G_FAPI_LOG(ERROR_LOG, (" [CRC.indication] No Valid data available "
159                 "for frame :%d, slot: %d, symbol: %d, urllc %u", frame_no, slot_no, symbol_no, is_urllc));
160         return FAILURE;
161     }
162
163     num_crc = p_fapi_crc_ind->numCrcs = p_phy_crc_ind->nCrc;
164     for (i = 0; i < num_crc; i++) {
165         p_stats->iapi_stats.iapi_crc_ind_pdus++;
166
167         p_fapi_crc_ind_info = &p_fapi_crc_ind->crc[i];
168         p_ul_crc_struct = &p_phy_crc_ind->sULCRCStruct[i];
169         p_pusch_info =
170             nr5g_fapi_get_pusch_info(p_ul_crc_struct->nUEId, p_ul_slot_info);
171
172         if (p_pusch_info == NULL) {
173             NR5G_FAPI_LOG(ERROR_LOG,
174                 (" [CRC.indication] No Valid data available "
175                     "nUEId:%d, frame_no:%d, slot_no:%d, urllc %u", p_ul_crc_struct->nUEId,
176                     frame_no, slot_no, is_urllc));
177             return FAILURE;
178         }
179
180         p_fapi_crc_ind_info->handle = p_pusch_info->handle;
181         p_fapi_crc_ind_info->rnti = p_ul_crc_struct->nRNTI;
182         p_fapi_crc_ind_info->harqId = p_pusch_info->harq_process_id;
183         p_fapi_crc_ind_info->tbCrcStatus = !(p_ul_crc_struct->nCrcFlag);
184         p_fapi_crc_ind_info->ul_cqi = nr5g_fapi_convert_snr_iapi_to_fapi(p_ul_crc_struct->nSNR);
185         if(p_fapi_snr)
186         {
187             p_fapi_snr->nSNR[i] = p_ul_crc_struct->nSNR;
188         }
189         p_pusch_info->ul_cqi = p_fapi_crc_ind_info->ul_cqi;
190
191         p_fapi_crc_ind_info->numCb = 0;
192         p_pusch_info->timing_advance = p_fapi_crc_ind_info->timingAdvance = 31;
193 #ifdef DEBUG_MODE
194         p_pusch_info->timing_advance = p_fapi_crc_ind_info->timingAdvance =
195             p_ul_crc_struct->nTA;
196 #endif
197         p_fapi_crc_ind_info->rssi = 880;
198
199         p_stats->fapi_stats.fapi_crc_ind_pdus++;
200     }
201     return SUCCESS;
202 }