* 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_rach_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 RACH.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
30  /** @ingroup group_source_api_p7_fapi2mac_proc
31  *
32  *  @param[in]  p_phy_ctx Pointer to PHY Context.
33  *  @param[in]  p_phy_rach_ind Pointer to FAPI RACH.indication message structure.
34  *  
35  *  @return     Returns ::SUCCESS and ::FAILURE.
36  *
37  *  @description
38  *  This message includes RACH PDU. 
39  *
40 **/
41 uint8_t nr5g_fapi_rach_indication(
42     bool is_urllc,
43     p_nr5g_fapi_phy_ctx_t p_phy_ctx,
44     PRXRACHIndicationStruct p_phy_rach_ind)
45 {
46     uint8_t phy_id;
47
48     fapi_rach_indication_t *p_fapi_rach_ind;
49     p_fapi_api_queue_elem_t p_list_elem;
50     p_nr5g_fapi_phy_instance_t p_phy_instance = NULL;
51     nr5g_fapi_stats_t *p_stats;
52
53     if (NULL == p_phy_ctx) {
54         NR5G_FAPI_LOG(ERROR_LOG, ("[RACH.indication] Invalid " "phy context"));
55         return FAILURE;
56     }
57
58     if (NULL == p_phy_rach_ind) {
59         NR5G_FAPI_LOG(ERROR_LOG, ("[RACH.indication] Invalid handle to phy "
60                 "RACH indication"));
61         return FAILURE;
62     }
63
64     phy_id = p_phy_rach_ind->sSFN_Slot.nCarrierIdx;
65     p_phy_instance = &p_phy_ctx->phy_instance[phy_id];
66     if ((p_phy_instance->phy_id != phy_id)) {
67         NR5G_FAPI_LOG(ERROR_LOG, ("[RACH.indication] Invalid " "phy instance"));
68         return FAILURE;
69     }
70
71     p_stats = &p_phy_instance->stats;
72     p_stats->iapi_stats.iapi_rach_ind++;
73
74     p_list_elem =
75         nr5g_fapi_fapi2mac_create_api_list_elem(FAPI_RACH_INDICATION, 1,
76         sizeof(fapi_rach_indication_t));
77
78     if (!p_list_elem) {
79         NR5G_FAPI_LOG(ERROR_LOG, ("[RACH.indication] Unable to create "
80                 "list element. Out of memory!!!"));
81         return FAILURE;
82     }
83
84     p_fapi_rach_ind = (fapi_rach_indication_t *) (p_list_elem + 1);
85     p_fapi_rach_ind->header.msg_id = FAPI_RACH_INDICATION;
86     p_fapi_rach_ind->header.length = (uint16_t) sizeof(fapi_rach_indication_t);
87
88     if (nr5g_fapi_rach_indication_to_fapi_translation(is_urllc, p_phy_instance,
89             p_phy_rach_ind, p_fapi_rach_ind)) {
90         NR5G_FAPI_LOG(ERROR_LOG,
91             ("[RACH.indication] L1 to FAPI " "translation failed"));
92         return FAILURE;
93     }
94
95     nr5g_fapi_fapi2mac_add_api_to_list(phy_id, p_list_elem, false);
96
97     p_stats->fapi_stats.fapi_rach_ind++;
98     NR5G_FAPI_LOG(DEBUG_LOG, ("[RACH.indication][%u][%u,%u,%u] is_urllc %u",
99             p_phy_instance->phy_id,
100             p_phy_rach_ind->sSFN_Slot.nSFN, p_phy_rach_ind->sSFN_Slot.nSlot,
101             p_phy_rach_ind->sSFN_Slot.nSym, is_urllc));
102
103     return SUCCESS;
104 }
105
106  /** @ingroup group_source_api_p7_fapi2mac_proc
107  *
108  *  @param[in]   slot_index Variable holding nStartSlotdx received in IAPI RACH.Indication.
109  *  @param[in]   freq_index Variable holding nFreqIdx received in IAPI RACH.Indication.
110  *  @param[in]   symbol_index Variable holding nSymbolIdx received in IAPI RACH.Indication.
111  *  @param[in]   num_pdus Variable holding the num_pdus filled in FAPI RACH.Indication till then.
112  *  @param[in]   p_fapi_rach_ind Pointer to FAPI RACH.indication structure.
113  *  
114  *  @return     Returns pdu_index at which slot_index and freq_index match occurs
115  *                         
116  *
117  *  @description
118  *  This function returns the pdu_index at which slot_index and freq_index match
119  *  occurs in FAPI RACH.Indication populated till then
120  *
121 **/
122 uint8_t nr5g_fapi_start_slot_freq_idx_occ(
123     uint8_t slot_index,
124     uint8_t freq_index,
125     uint8_t symbol_index,
126     uint8_t num_pdus,
127     fapi_rach_indication_t * p_fapi_rach_ind)
128 {
129     uint8_t i, pdu_index = 0xFF;
130
131     fapi_rach_pdu_t *p_fapi_rach_pdu;
132
133     for (i = 0; i < num_pdus; i++) {
134         p_fapi_rach_pdu = &p_fapi_rach_ind->rachPdu[i];
135         if ((slot_index == p_fapi_rach_pdu->slotIndex)
136             && (freq_index == p_fapi_rach_pdu->freqIndex)
137             && (symbol_index == p_fapi_rach_pdu->symbolIndex)) {
138             pdu_index = i;
139             break;
140         }
141     }
142     return pdu_index;
143 }
144
145  /** @ingroup group_source_api_p7_fapi2mac_proc
146  *
147  *  @param[in]  p_phy_instance Pointer to PHY instance.
148  *  @param[in]   p_phy_rach_ind Pointer to IAPI RACH.indication structure.
149  *  @param[out]  p_fapi_rach_ind Pointer to FAPI RACH.indication structure.
150  *  
151  *  @return     Returns ::SUCCESS and ::FAILURE.
152  *
153  *  @description
154  *  This function converts IAPI RACH.indication to FAPI RACH.indication
155  *  structure.
156  *
157 **/
158 uint8_t nr5g_fapi_rach_indication_to_fapi_translation(
159     bool is_urllc,
160     p_nr5g_fapi_phy_instance_t p_phy_instance,
161     PRXRACHIndicationStruct p_phy_rach_ind,
162     fapi_rach_indication_t * p_fapi_rach_ind)
163 {
164     uint8_t num_preamble, num_pdus = 0, i;
165     uint8_t symbol_no, preamble_no;
166     uint8_t slot_freq_idx_entry;
167     uint8_t slot_index, freq_index, symbol_index;
168     uint16_t slot_no, frame_no;
169
170     fapi_rach_pdu_t *p_fapi_rach_pdu;
171     fapi_rach_pdu_t *p_fapi_rach_pdu_match;
172     fapi_preamble_info_t *p_fapi_preamble_info;
173     nr5g_fapi_ul_slot_info_t *p_ul_slot_info;
174     nr5g_fapi_stats_t *p_stats;
175     PreambleStruct *p_phy_preamble_struct;
176
177     p_stats = &p_phy_instance->stats;
178
179     frame_no = p_fapi_rach_ind->sfn = p_phy_rach_ind->sSFN_Slot.nSFN;
180     slot_no = p_fapi_rach_ind->slot = p_phy_rach_ind->sSFN_Slot.nSlot;
181     symbol_no = p_phy_rach_ind->sSFN_Slot.nSym;
182
183     p_ul_slot_info =
184         nr5g_fapi_get_ul_slot_info(is_urllc, frame_no, slot_no, symbol_no, p_phy_instance);
185
186     if (p_ul_slot_info == NULL) {
187         NR5G_FAPI_LOG(ERROR_LOG, ("[RACH.indication] No Valid data available "
188                 "for frame :%d and slot: %d", frame_no, slot_no));
189         return FAILURE;
190     }
191
192     if (p_ul_slot_info->rach_presence == 0) {
193         NR5G_FAPI_LOG(ERROR_LOG, ("[RACHindication] RACH is not requested"
194                 "for frame :%d and slot: %d", frame_no, slot_no));
195         return FAILURE;
196     }
197
198     num_preamble = p_phy_rach_ind->nNrOfPreamb;
199     for (i = 0; i < num_preamble; i++) {
200         p_stats->iapi_stats.iapi_rach_preambles++;
201         p_phy_preamble_struct = &p_phy_rach_ind->sPreambleStruct[i];
202         slot_index = p_phy_preamble_struct->nStartSlotdx;
203         freq_index = p_phy_preamble_struct->nFreqIdx;
204         symbol_index = p_phy_preamble_struct->nStartSymbIdx;
205         //returns 0xFF if its a new preamble, else pdu index of p_fapi_rach_ind;
206         slot_freq_idx_entry = nr5g_fapi_start_slot_freq_idx_occ(slot_index,
207             freq_index, symbol_index, num_pdus, p_fapi_rach_ind);
208         if (slot_freq_idx_entry == 0xFF) {
209             p_fapi_rach_pdu = &p_fapi_rach_ind->rachPdu[i];
210             p_fapi_rach_pdu->phyCellId = p_ul_slot_info->rach_info.phy_cell_id;
211             p_fapi_rach_pdu->numPreamble = 0;
212             p_fapi_rach_pdu->symbolIndex = p_phy_preamble_struct->nStartSymbIdx;
213             p_fapi_rach_pdu->slotIndex = slot_index;
214             p_fapi_rach_pdu->freqIndex = freq_index;
215             p_fapi_rach_pdu->avgRssi = 0xFF;
216             p_fapi_rach_pdu->avgSnr = 0xFF;
217             preamble_no = p_fapi_rach_pdu->numPreamble++;
218             p_fapi_preamble_info = &p_fapi_rach_pdu->preambleInfo[preamble_no];
219             num_pdus++;
220             p_stats->fapi_stats.fapi_rach_ind_pdus++;
221         } else {
222             p_fapi_rach_pdu_match =
223                 &p_fapi_rach_ind->rachPdu[slot_freq_idx_entry];
224             preamble_no = p_fapi_rach_pdu_match->numPreamble++;
225             p_fapi_preamble_info =
226                 &p_fapi_rach_pdu_match->preambleInfo[preamble_no];
227         }
228         p_fapi_preamble_info->preambleIndex = p_phy_preamble_struct->nPreambIdx;
229         p_fapi_preamble_info->timingAdvance = p_phy_preamble_struct->nTa;
230         p_fapi_preamble_info->preamblePwr = p_phy_preamble_struct->nPreambPwr;
231     }
232     p_fapi_rach_ind->numPdus = num_pdus;
233
234     return SUCCESS;
235 }