1 /******************************************************************************
3 * Copyright (c) 2021 Intel.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 *******************************************************************************/
21 * This file consist of implementation of FAPI CRC.indication message.
25 #include "nr5g_mac_phy_api.h"
26 #include "nr5g_fapi_framework.h"
27 #include "nr5g_fapi_fapi2mac_api.h"
28 #include "nr5g_fapi_fapi2mac_p7_proc.h"
29 #include "nr5g_fapi_fapi2mac_p7_pvt_proc.h"
31 /** @ingroup group_source_api_p7_fapi2mac_proc
33 * @param[in] p_phy_ctx Pointer to PHY Context.
34 * @param[in] p_phy_rx_data_ind Pointer to FAPI RX_DATA.indication message structure.
36 * @return Returns ::SUCCESS and ::FAILURE.
39 * This message includes RX_DATA to be sent to L2.
42 uint8_t nr5g_fapi_rx_data_indication(
44 p_nr5g_fapi_phy_ctx_t p_phy_ctx,
45 p_fapi_api_stored_vendor_queue_elems vendor_extension_elems,
46 PRXULSCHIndicationStruct p_phy_rx_ulsch_ind)
49 fapi_rx_data_indication_t *p_fapi_rx_data_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;
54 if (NULL == p_phy_ctx) {
55 NR5G_FAPI_LOG(ERROR_LOG, ("[NR5G_FAPI][RX_DATA.indication] Invalid "
60 if (NULL == p_phy_rx_ulsch_ind) {
61 NR5G_FAPI_LOG(ERROR_LOG, ("[NR5G_FAPI][RX_DATA.indication] Invalid "
62 "RX_USLCH indication"));
66 phy_id = p_phy_rx_ulsch_ind->sSFN_Slot.nCarrierIdx;
67 p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
68 if (p_phy_instance->phy_id != phy_id) {
69 NR5G_FAPI_LOG(ERROR_LOG, ("[NR5G_FAPI][RX_DATA.indication] Invalid "
70 "handle to phy instance"));
74 p_stats = &p_phy_instance->stats;
75 p_stats->iapi_stats.iapi_rx_data_ind++;
78 nr5g_fapi_fapi2mac_create_api_list_elem(FAPI_RX_DATA_INDICATION, 1,
79 sizeof(fapi_rx_data_indication_t));
82 NR5G_FAPI_LOG(ERROR_LOG,
83 ("[NR5G_FAPI][RX_DATA.indication] Unable to create "
84 "list element. Out of memory!!!"));
88 p_fapi_rx_data_ind = (fapi_rx_data_indication_t *) (p_list_elem + 1);
89 p_fapi_rx_data_ind->header.msg_id = FAPI_RX_DATA_INDICATION;
90 p_fapi_rx_data_ind->header.length =
91 (uint16_t) sizeof(fapi_rx_data_indication_t);
93 fapi_vendor_p7_ind_msg_t* p_fapi_vend_p7 =
94 nr5g_fapi_proc_vendor_p7_msg_get(vendor_extension_elems, phy_id);
95 fapi_vendor_ext_rx_data_ind_t* p_fapi_vend_rx_data_ind =
96 p_fapi_vend_p7 ? &p_fapi_vend_p7->rx_data_ind : NULL;
98 if (p_fapi_vend_rx_data_ind) {
99 p_fapi_vend_rx_data_ind->carrier_idx = phy_id;
100 p_fapi_vend_rx_data_ind->sym = p_phy_rx_ulsch_ind->sSFN_Slot.nSym;
103 if (nr5g_fapi_rx_data_indication_to_fapi_translation(is_urllc, p_phy_instance,
104 p_phy_rx_ulsch_ind, p_fapi_rx_data_ind)) {
105 NR5G_FAPI_LOG(ERROR_LOG, ("[NR5G_FAPI][RX_DATA.indication] L1 to FAPI "
106 "translation failed"));
110 nr5g_fapi_fapi2mac_add_api_to_list(phy_id, p_list_elem, is_urllc);
112 p_stats->fapi_stats.fapi_rx_data_ind++;
113 NR5G_FAPI_LOG(DEBUG_LOG, ("[RX_DATA.indication][%u][%u,%u,%u] is_urllc %u",
114 p_phy_instance->phy_id,
115 p_phy_rx_ulsch_ind->sSFN_Slot.nSFN, p_phy_rx_ulsch_ind->sSFN_Slot.nSlot,
116 p_phy_rx_ulsch_ind->sSFN_Slot.nSym, is_urllc));
121 /** @ingroup group_source_api_p7_fapi2mac_proc
123 * @param[in] ue_id Variable holding ue_id received in RX_DATA.Indication..
124 * @param[in] p_ul_slot_info Pointer to ul slot info structure that stores the
125 * UL_TTI.request PDU info.
127 * @return Returns Pointer to pusch info, if handle of p_ul_slot_info matches ue_id.
128 NULL, if handle of p_ul_slot_info not matches ue_id
131 * This function retrieves the pusch info stored during corresponding UL_TTI.request processing.
135 nr5g_fapi_pusch_info_t *nr5g_fapi_get_pusch_info(
137 nr5g_fapi_ul_slot_info_t * p_ul_slot_info)
139 uint8_t i, num_ulsch;
141 nr5g_fapi_pusch_info_t *p_pusch_info;
143 num_ulsch = p_ul_slot_info->num_ulsch;
144 for (i = 0; i < num_ulsch; i++) {
145 p_pusch_info = &p_ul_slot_info->pusch_info[i];
146 if (p_pusch_info->handle == ue_id) {
153 /** @ingroup group_source_api_p7_fapi2mac_proc
155 * @param[in] p_phy_instance Pointer to PHY instance.
156 * @param[in] p_phy_rx_ulsch_ind Pointer to IAPI RX_ULSCH.indication structure.
157 * @param[out] p_fapi_rx_data_ind Pointer to FAPI RX_DATA.indication structure.
159 * @return Returns ::SUCCESS and ::FAILURE.
162 * This function converts IAPI RX_DATA.indication to FAPI CRC.indication
166 uint8_t nr5g_fapi_rx_data_indication_to_fapi_translation(
168 p_nr5g_fapi_phy_instance_t p_phy_instance,
169 PRXULSCHIndicationStruct p_phy_rx_ulsch_ind,
170 fapi_rx_data_indication_t * p_fapi_rx_data_ind)
172 uint8_t num_ulsch, i;
174 uint16_t slot_no, frame_no;
176 nr5g_fapi_pusch_info_t *p_pusch_info;
177 fapi_pdu_ind_info_t *p_fapi_pdu_ind_info;
178 nr5g_fapi_ul_slot_info_t *p_ul_slot_info;
179 nr5g_fapi_stats_t *p_stats;
180 ULSCHPDUDataStruct *p_rx_ulsch_pdu_data;
182 p_stats = &p_phy_instance->stats;
184 frame_no = p_fapi_rx_data_ind->sfn = p_phy_rx_ulsch_ind->sSFN_Slot.nSFN;
185 slot_no = p_fapi_rx_data_ind->slot = p_phy_rx_ulsch_ind->sSFN_Slot.nSlot;
186 symbol_no = p_phy_rx_ulsch_ind->sSFN_Slot.nSym;
189 nr5g_fapi_get_ul_slot_info(is_urllc, frame_no, slot_no, symbol_no, p_phy_instance);
191 if (p_ul_slot_info == NULL) {
192 NR5G_FAPI_LOG(ERROR_LOG,
193 ("[NR5G_FAPI] [RX_DATA.indication] No Valid data available "
194 "for frame :%d and slot: %d", frame_no, slot_no));
198 num_ulsch = p_fapi_rx_data_ind->numPdus = p_phy_rx_ulsch_ind->nUlsch;
199 for (i = 0; i < num_ulsch; i++) {
200 p_stats->iapi_stats.iapi_rx_data_ind_pdus++;
201 p_fapi_pdu_ind_info = &p_fapi_rx_data_ind->pdus[i];
202 p_rx_ulsch_pdu_data = &p_phy_rx_ulsch_ind->sULSCHPDUDataStruct[i];
204 nr5g_fapi_get_pusch_info(p_rx_ulsch_pdu_data->nUEId,
206 if (p_pusch_info == NULL) {
207 NR5G_FAPI_LOG(ERROR_LOG,
208 ("[NR5G_FAPI] [RX_DATA.indication] No Valid data available "
209 "nUEId:%d, frame_no:%d, slot_no:%d, urllc %u",
210 p_rx_ulsch_pdu_data->nUEId, frame_no, slot_no, is_urllc));
214 p_fapi_pdu_ind_info->handle = p_pusch_info->handle;
215 p_fapi_pdu_ind_info->rnti = p_rx_ulsch_pdu_data->nRNTI;
216 // upper nibble of pdu_length is passed in upper nibble in harqId (which only takes up to 4 bits)
217 // this way, pdu_length has 20-bits (up to 1048576)
218 p_fapi_pdu_ind_info->harqId = ((p_rx_ulsch_pdu_data->nPduLen & 0x000F0000) >> 12) | (p_pusch_info->harq_process_id & 0x0F);
219 p_fapi_pdu_ind_info->ul_cqi = p_pusch_info->ul_cqi;
220 p_fapi_pdu_ind_info->timingAdvance = p_pusch_info->timing_advance;
221 p_fapi_pdu_ind_info->rssi = 880;
222 p_fapi_pdu_ind_info->pdu_length = 0xFFFF & p_rx_ulsch_pdu_data->nPduLen;
223 p_fapi_pdu_ind_info->pduData = (void *)p_rx_ulsch_pdu_data->pPayload;
225 p_stats->fapi_stats.fapi_rx_data_ind_pdus++;