3e8b23afd22ac6e73bb9ddb54abef3cbd38138ce
[o-du/l2.git] / src / 5gnrsch / sch_utils.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
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 /************************************************************************
20  
21      Name:     sch_utils.c
22   
23      Type:     C source file
24   
25      Desc:     C source code for scheduler utilities
26   
27      File:     sch_utils.c
28   
29 **********************************************************************/
30
31 /** @file sch_utils.c
32 @brief This file implements the schedulers util functions.
33 */
34
35 /* header files */
36 #include "common_def.h"
37 #include "du_app_mac_inf.h"
38 #include "lrg.h"
39 #include "tfu.h"
40 #include "tfu.x"           /* TFU types */
41 #include "lrg.x"           /* layer management typedefs for MAC */
42 #include "mac_sch_interface.h"
43 #include "sch.h"
44 #include "sch_tmr.h"
45 #include "sch_utils.h"
46 #include "math.h"
47
48 #ifdef NR_TDD
49 /* spec-38.213 Table 13-4 for SCS=30KHz */
50 /* Note: Picking Table 13-4 and not 13-6 since band supported is n78 and
51  * corresponding minimum B/W is 10 MHz */
52 int8_t coresetIdxTable[MAX_CORESET_INDEX][4] = {
53 {   1,   24,   2,   0}, /* index 0  */
54 {   1,   24,   2,   1}, /* index 1  */
55 {   1,   24,   2,   2}, /* index 2  */
56 {   1,   24,   2,   3}, /* index 3  */
57 {   1,   24,   2,   4}, /* index 4  */
58 {   1,   24,   3,   0}, /* index 5  */
59 {   1,   24,   3,   1}, /* index 6  */
60 {   1,   24,   3,   2}, /* index 7  */
61 {   1,   24,   3,   3}, /* index 8  */
62 {   1,   24,   3,   4}, /* index 9  */
63 {   1,   48,   1,  12}, /* index 10 */
64 {   1,   48,   1,  14}, /* index 11 */
65 {   1,   48,   1,  16}, /* index 12 */
66 {   1,   48,   2,  12}, /* index 13 */
67 {   1,   48,   2,  14}, /* index 14 */
68 {   1,   48,   2,  16}, /* index 15 */
69 };
70 #else
71 /* spec-38.213 Table 13-1 for SCS=15KHz */
72 int8_t coresetIdxTable[MAX_CORESET_INDEX][4] = {
73 {   1,   24,   2,   0}, /* index 0  */
74 {   1,   24,   2,   2}, /* index 1  */
75 {   1,   24,   2,   4}, /* index 2  */
76 {   1,   24,   3,   0}, /* index 3  */
77 {   1,   24,   3,   2}, /* index 4  */
78 {   1,   24,   3,   4}, /* index 5  */
79 {   1,   48,   1,  12}, /* index 6  */
80 {   1,   48,   1,  16}, /* index 7  */
81 {   1,   48,   2,  12}, /* index 8  */
82 {   1,   48,   2,  16}, /* index 9  */
83 {   1,   48,   3,  12}, /* index 10 */
84 {   1,   48,   3,  16}, /* index 11 */
85 {   1,   96,   1,  38}, /* index 12 */
86 {   1,   96,   2,  38}, /* index 13 */
87 {   1,   96,   3,  38}, /* index 14 */
88 {   0,    0,   0,   0}, /* index 15 */
89 };
90 #endif
91
92 /* spec-38.213 Table 13-11 */
93 /* m value is scaled to 2, when using it in formula, divide by 2 */
94 /* firstSymbol will vary depends on i, hence not filled */
95 int8_t searchSpaceIdxTable[MAX_SEARCH_SPACE_INDEX][4] = {
96 {   0,    1,   2,   0}, /* index 0  */
97 {   0,    2,   1,   0}, /* index 1  */
98 {   2,    1,   2,   0}, /* index 2  */
99 {   2,    2,   1,   0}, /* index 3  */
100 {   5,    1,   2,   0}, /* index 4  */
101 {   5,    2,   1,   0}, /* index 5  */
102 {   7,    1,   2,   0}, /* index 6  */
103 {   7,    2,   1,   0}, /* index 7  */
104 {   0,    1,   4,   0}, /* index 8  */
105 {   5,    1,   4,   0}, /* index 9  */
106 {   0,    1,   2,   0}, /* index 10 */
107 {   0,    1,   2,   0}, /* index 11 */
108 {   2,    1,   2,   0}, /* index 12 */
109 {   2,    1,   2,   0}, /* index 13 */
110 {   5,    1,   2,   0}, /* index 14 */
111 {   5,    1,   2,   0}, /* index 15 */
112 };
113
114 /* RACH tables */
115
116 /* spec-38.211 Table 6.3.3.2-1 */
117 /* Lra, delFRa, delF, numRb, k' */
118 uint16_t numRbForPrachTable[MAX_RACH_NUM_RB_IDX][5] = {
119 {   839,  1.25,  15,   6,   7    }, /* index 0 */
120 {   839,  1.25,  30,   3,   1    }, /* index 1 */
121 {   839,  1.25,  60,   2,   133  }, /* index 2 */
122 {   839,  5,     15,   24,  12   }, /* index 3 */
123 {   839,  5,     30,   12,  10   }, /* index 4 */
124 {   839,  5,     60,   6,   7    }, /* index 5 */
125 {   139,  15,    15,   12,  2    }, /* index 6 */
126 {   139,  15,    30,   6,   2    }, /* index 7 */
127 {   139,  15,    60,   3,   2    }, /* index 8 */
128 {   139,  30,    15,   24,  2    }, /* index 9 */
129 {   139,  30,    30,   12,  2    }, /* index 10 */
130 {   139,  30,    60,   6,   2    }, /* index 11 */
131 {   139,  60,    60,   12,  2    }, /* index 12 */
132 {   139,  60,    120,  6,   2    }, /* index 13 */
133 {   139,  120,   60,   24,  2    }, /* index 14 */
134 {   139,  120,   120,  12,  2    }, /* index 15 */
135 };
136
137 #ifdef NR_TDD
138
139 /* prach config index Table 6.3.3.2-3 spec 38.211 
140  * PRACH format given as follows:
141  * 0 = 0
142  * 1 = 1
143  * 2 = 2
144  * 3 = 3
145  * 4 = A1
146  * 5 = A2
147  * 6 = A3
148  * 7 = B1
149  * 8 = B4
150  * 9 = C0
151  * 10 = C2
152  * 11 = A1/B1
153  * 12 = A2/B2
154  * 13 = A3/B3 
155  * Subframe num is represented considering 0-9 bits and
156  * value 1 corresponds to the subframe that is valid 
157  */
158
159 uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8] = {
160 { 0, 16,  1,  512,  0,  0,  0,  0 }, /* index 0   */
161 { 0,  8,  1,  512,  0,  0,  0,  0 }, /* index 1   */
162 { 0,  4,  1,  512,  0,  0,  0,  0 }, /* index 2   */
163 { 0,  2,  0,  512,  0,  0,  0,  0 }, /* index 3   */
164 { 0,  2,  1,  512,  0,  0,  0,  0 }, /* index 4   */
165 { 0,  2,  0,   16,  0,  0,  0,  0 }, /* index 5   */
166 { 0,  2,  1,   16,  0,  0,  0,  0 }, /* index 6   */
167 { 0,  1,  0,  512,  0,  0,  0,  0 }, /* index 7   */
168 { 0,  1,  0,  256,  0,  0,  0,  0 }, /* index 8   */
169 { 0,  1,  0,  128,  0,  0,  0,  0 }, /* index 9   */
170 { 0,  1,  0,   64,  0,  0,  0,  0 }, /* index 10  */
171 { 0,  1,  0,   32,  0,  0,  0,  0 }, /* index 11  */
172 { 0,  1,  0,   16,  0,  0,  0,  0 }, /* index 12  */
173 { 0,  1,  0,    8,  0,  0,  0,  0 }, /* index 13  */
174 { 0,  1,  0,    4,  0,  0,  0,  0 }, /* index 14  */
175 { 0,  1,  0,   66,  0,  0,  0,  0 }, /* index 15  */
176 { 0,  1,  0,   66,  7,  0,  0,  0 }, /* index 16  */
177 { 0,  1,  0,  528,  0,  0,  0,  0 }, /* index 17  */
178 { 0,  1,  0,  264,  0,  0,  0,  0 }, /* index 18  */
179 { 0,  1,  0,  132,  0,  0,  0,  0 }, /* index 19  */
180 { 0,  1,  0,  768,  0,  0,  0,  0 }, /* index 20  */
181 { 0,  1,  0,  784,  0,  0,  0,  0 }, /* index 21  */
182 { 0,  1,  0,  536,  0,  0,  0,  0 }, /* index 22  */
183 { 0,  1,  0,  896,  0,  0,  0,  0 }, /* index 23  */
184 { 0,  1,  0,  792,  0,  0,  0,  0 }, /* index 24  */
185 { 0,  1,  0,  960,  0,  0,  0,  0 }, /* index 25  */
186 { 0,  1,  0,  594,  0,  0,  0,  0 }, /* index 26  */
187 { 0,  1,  0,  682,  0,  0,  0,  0 }, /* index 27  */
188 { 1, 16,  1,  128,  0,  0,  0,  0 }, /* index 28  */
189 { 1,  8,  1,  128,  0,  0,  0,  0 }, /* index 29  */
190 { 1,  4,  1,  128,  0,  0,  0,  0 }, /* index 30  */
191 { 1,  2,  0,  128,  0,  0,  0,  0 }, /* index 31  */
192 { 1,  2,  1,  128,  0,  0,  0,  0 }, /* index 32  */
193 { 1,  1,  0,  128,  0,  0,  0,  0 }, /* index 33  */
194 { 2, 16,  1,   64,  0,  0,  0,  0 }, /* index 34  */
195 { 2,  8,  1,   64,  0,  0,  0,  0 }, /* index 35  */
196 { 2,  4,  1,   64,  0,  0,  0,  0 }, /* index 36  */
197 { 2,  2,  0,   64,  7,  0,  0,  0 }, /* index 37  */
198 { 2,  2,  1,   64,  7,  0,  0,  0 }, /* index 38  */
199 { 2,  1,  0,   64,  7,  0,  0,  0 }, /* index 39  */
200 { 3, 16,  1,  512,  0,  0,  0,  0 }, /* index 40  */
201 { 3,  8,  1,  512,  0,  0,  0,  0 }, /* index 41  */
202 { 3,  4,  1,  512,  0,  0,  0,  0 }, /* index 42  */
203 { 3,  2,  0,  512,  0,  0,  0,  0 }, /* index 43  */
204 { 3,  2,  1,  512,  0,  0,  0,  0 }, /* index 44  */
205 { 3,  2,  0,   16,  0,  0,  0,  0 }, /* index 45  */
206 { 3,  2,  1,   16,  0,  0,  0,  0 }, /* index 46  */
207 { 3,  1,  0,  512,  0,  0,  0,  0 }, /* index 47  */
208 { 3,  1,  0,  256,  0,  0,  0,  0 }, /* index 48  */
209 { 3,  1,  0,  128,  0,  0,  0,  0 }, /* index 49  */
210 { 3,  1,  0,   64,  0,  0,  0,  0 }, /* index 50  */
211 { 3,  1,  0,   32,  0,  0,  0,  0 }, /* index 51  */
212 { 3,  1,  0,   16,  0,  0,  0,  0 }, /* index 52  */
213 { 3,  1,  0,    8,  0,  0,  0,  0 }, /* index 53  */
214 { 3,  1,  0,    4,  0,  0,  0,  0 }, /* index 54  */
215 { 3,  1,  0,   66,  0,  0,  0,  0 }, /* index 55  */
216 { 3,  1,  0,   66,  7,  0,  0,  0 }, /* index 56  */
217 { 3,  1,  0,  528,  0,  0,  0,  0 }, /* index 57  */
218 { 3,  1,  0,  264,  0,  0,  0,  0 }, /* index 58  */
219 { 3,  1,  0,  132,  0,  0,  0,  0 }, /* index 59  */
220 { 3,  1,  0,  768,  0,  0,  0,  0 }, /* index 60  */
221 { 3,  1,  0,  784,  0,  0,  0,  0 }, /* index 61  */
222 { 3,  1,  0,  536,  0,  0,  0,  0 }, /* index 62  */
223 { 3,  1,  0,  896,  0,  0,  0,  0 }, /* index 63  */
224 { 3,  1,  0,  792,  0,  0,  0,  0 }, /* index 64  */
225 { 3,  1,  0,  594,  0,  0,  0,  0 }, /* index 65  */
226 { 3,  1,  0,  682,  0,  0,  0,  0 }, /* index 66  */
227 { 4, 16,  1,  512,  0,  2,  6,  2 }, /* index 67  */
228 { 4,  8,  1,  512,  0,  2,  6,  2 }, /* index 68  */
229 { 4,  4,  1,  512,  0,  1,  6,  2 }, /* index 69  */
230 { 4,  2,  1,  512,  0,  1,  6,  2 }, /* index 70  */
231 { 4,  2,  1,  528,  7,  1,  3,  2 }, /* index 71  */
232 { 4,  2,  1,  640,  7,  1,  3,  2 }, /* index 72  */
233 { 4,  2,  1,  640,  0,  1,  6,  2 }, /* index 73  */
234 { 4,  2,  1,  768,  0,  2,  6,  2 }, /* index 74  */
235 { 4,  2,  1,  528,  0,  2,  6,  2 }, /* index 75  */
236 { 4,  2,  1,  924,  0,  1,  6,  2 }, /* index 76  */
237 { 4,  1,  0,  512,  0,  2,  6,  2 }, /* index 77  */
238 { 4,  1,  0,  512,  7,  1,  3,  2 }, /* index 78  */
239 { 4,  1,  0,  512,  0,  1,  6,  2 }, /* index 79  */
240 { 4,  1,  0,  768,  0,  2,  6,  2 }, /* index 80  */
241 { 4,  1,  0,  528,  0,  1,  6,  2 }, /* index 81  */
242 { 4,  1,  0,  640,  7,  1,  3,  2 }, /* index 82  */
243 { 4,  1,  0,  792,  0,  1,  6,  2 }, /* index 83  */
244 { 4,  1,  0,  792,  0,  2,  6,  2 }, /* index 84  */
245 { 4,  1,  0,  682,  0,  1,  6,  2 }, /* index 85  */
246 { 4,  1,  0, 1023,  7,  1,  3,  2 }, /* index 86  */
247 { 5, 16,  1,  512,  0,  2,  3,  4 }, /* index 87  */
248 { 5,  8,  1,  512,  0,  2,  3,  4 }, /* index 88  */
249 { 5,  4,  1,  512,  0,  1,  3,  4 }, /* index 89  */
250 { 5,  2,  1,  640,  0,  1,  3,  4 }, /* index 90  */
251 { 5,  2,  1,  768,  0,  2,  3,  4 }, /* index 91  */
252 { 5,  2,  1,  640,  9,  1,  1,  4 }, /* index 92  */
253 { 5,  2,  1,  528,  9,  1,  1,  4 }, /* index 93  */
254 { 5,  2,  1,  528,  0,  2,  3,  4 }, /* index 94  */
255 { 5,  2,  1,  924,  0,  1,  3,  4 }, /* index 95  */
256 { 5,  1,  0,    4,  0,  1,  3,  4 }, /* index 96  */
257 { 5,  1,  0,  128,  0,  1,  3,  4 }, /* index 97  */
258 { 5,  2,  1,  512,  0,  1,  3,  4 }, /* index 98  */
259 { 5,  1,  0,  512,  0,  2,  3,  4 }, /* index 99  */
260 { 5,  1,  0,  512,  9,  1,  1,  4 }, /* index 100  */
261 { 5,  1,  0,  512,  0,  1,  3,  4 }, /* index 101  */
262 { 5,  1,  0,  132,  0,  1,  3,  4 }, /* index 102  */
263 { 5,  1,  0,  768,  0,  2,  3,  4 }, /* index 103  */
264 { 5,  1,  0,  528,  0,  1,  3,  4 }, /* index 104  */
265 { 5,  1,  0,  640,  9,  1,  1,  4 }, /* index 105  */
266 { 5,  1,  0,  792,  0,  1,  3,  4 }, /* index 106  */
267 { 5,  1,  0,  792,  0,  2,  3,  4 }, /* index 107  */
268 { 5,  1,  0,  682,  0,  1,  3,  4 }, /* index 108  */
269 { 5,  1,  0, 1023,  9,  1,  1,  4 }, /* index 109  */
270 { 6, 16,  1,  512,  0,  2,  2,  6 }, /* index 110  */
271 { 6,  8,  1,  512,  0,  2,  2,  6 }, /* index 111  */
272 { 6,  4,  1,  512,  0,  1,  2,  6 }, /* index 112  */
273 { 6,  2,  1,  528,  7,  1,  1,  6 }, /* index 113  */
274 { 6,  2,  1,  640,  7,  1,  1,  6 }, /* index 114  */
275 { 6,  2,  1,  640,  0,  1,  2,  6 }, /* index 115  */
276 { 6,  2,  1,  528,  0,  2,  2,  6 }, /* index 116  */
277 { 6,  2,  1,  768,  0,  2,  2,  6 }, /* index 117  */
278 { 6,  2,  1,  924,  0,  1,  2,  6 }, /* index 118  */
279 { 6,  1,  0,    4,  0,  1,  2,  6 }, /* index 119  */
280 { 6,  1,  0,  128,  0,  1,  2,  6 }, /* index 120  */
281 { 6,  2,  1,  512,  0,  1,  2,  6 }, /* index 121  */
282 { 6,  1,  0,  512,  0,  2,  2,  6 }, /* index 122  */
283 { 6,  1,  0,  512,  7,  1,  1,  6 }, /* index 123  */
284 { 6,  1,  0,  512,  0,  1,  2,  6 }, /* index 124  */
285 { 6,  1,  0,  132,  0,  1,  2,  6 }, /* index 125  */
286 { 6,  1,  0,  768,  0,  2,  2,  6 }, /* index 126  */
287 { 6,  1,  0,  528,  0,  1,  2,  6 }, /* index 127  */
288 { 6,  1,  0,  640,  7,  1,  1,  6 }, /* index 128  */
289 { 6,  1,  0,  792,  0,  1,  2,  6 }, /* index 129  */
290 { 6,  1,  0,  792,  0,  2,  2,  6 }, /* index 130  */
291 { 6,  1,  0,  682,  0,  1,  2,  6 }, /* index 131  */
292 { 6,  1,  0, 1023,  7,  1,  1,  6 }, /* index 132  */
293 { 7,  4,  1,  512,  2,  1,  6,  2 }, /* index 133  */
294 { 7,  2,  1,  512,  2,  1,  6,  2 }, /* index 134  */
295 { 7,  2,  1,  640,  2,  1,  6,  2 }, /* index 135  */
296 { 7,  2,  1,  528,  8,  1,  3,  2 }, /* index 136  */
297 { 7,  2,  1,  528,  2,  2,  6,  2 }, /* index 137  */
298 { 7,  1,  0,  512,  2,  2,  6,  2 }, /* index 138  */
299 { 7,  1,  0,  512,  8,  1,  3,  2 }, /* index 139  */
300 { 7,  1,  0,  512,  2,  1,  6,  2 }, /* index 140  */
301 { 7,  1,  0,  768,  2,  2,  6,  2 }, /* index 141  */
302 { 7,  1,  0,  528,  2,  1,  6,  2 }, /* index 142  */
303 { 7,  1,  0,  640,  8,  1,  3,  2 }, /* index 143  */
304 { 7,  1,  0,  682,  2,  1,  6,  2 }, /* index 144  */
305 { 8, 16,  1,  512,  0,  2,  1, 12 }, /* index 145  */
306 { 8,  8,  1,  512,  0,  2,  1, 12 }, /* index 146  */
307 { 8,  4,  1,  512,  2,  1,  1, 12 }, /* index 147  */
308 { 8,  2,  1,  512,  0,  1,  1, 12 }, /* index 148  */
309 { 8,  2,  1,  512,  2,  1,  1, 12 }, /* index 149  */
310 { 8,  2,  1,  640,  2,  1,  1, 12 }, /* index 150  */
311 { 8,  2,  1,  528,  2,  1,  1, 12 }, /* index 151  */
312 { 8,  2,  1,  528,  0,  2,  1, 12 }, /* index 152  */
313 { 8,  2,  1,  768,  0,  2,  1, 12 }, /* index 153  */
314 { 8,  2,  1,  924,  0,  1,  1, 12 }, /* index 154  */
315 { 8,  1,  0,    2,  0,  1,  1, 12 }, /* index 155  */
316 { 8,  1,  0,    4,  0,  1,  1, 12 }, /* index 156  */
317 { 8,  1,  0,   16,  0,  1,  1, 12 }, /* index 157  */
318 { 8,  1,  0,  128,  0,  1,  1, 12 }, /* index 158  */
319 { 8,  1,  0,  512,  0,  1,  1, 12 }, /* index 159  */
320 { 8,  1,  0,  512,  2,  1,  1, 12 }, /* index 160  */
321 { 8,  1,  0,  512,  0,  2,  1, 12 }, /* index 161  */
322 { 8,  1,  0,  528,  2,  1,  1, 12 }, /* index 162  */
323 { 8,  1,  0,  640,  2,  1,  1, 12 }, /* index 163  */
324 { 8,  1,  0,  768,  0,  2,  1, 12 }, /* index 164  */
325 { 8,  1,  0,  792,  2,  1,  1, 12 }, /* index 165  */
326 { 8,  1,  0,  682,  2,  1,  1, 12 }, /* index 166  */
327 { 8,  1,  0, 1023,  0,  2,  1, 12 }, /* index 167  */
328 { 8,  1,  0, 1023,  2,  1,  1, 12 }, /* index 168  */
329 { 9, 16,  1,  512,  2,  2,  6,  2 }, /* index 169  */
330 { 9,  8,  1,  512,  2,  2,  6,  2 }, /* index 170  */
331 { 9,  4,  1,  512,  2,  1,  6,  2 }, /* index 171  */
332 { 9,  2,  1,  512,  2,  1,  6,  2 }, /* index 172  */
333 { 9,  2,  1,  768,  2,  2,  6,  2 }, /* index 173  */
334 { 9,  2,  1,  640,  2,  1,  6,  2 }, /* index 174  */
335 { 9,  2,  1,  640,  8,  1,  3,  2 }, /* index 175  */
336 { 9,  2,  1,  528,  8,  1,  3,  2 }, /* index 176  */
337 { 9,  2,  1,  528,  2,  2,  6,  2 }, /* index 177  */
338 { 9,  2,  1,  924,  2,  1,  6,  2 }, /* index 178  */
339 { 9,  1,  0,  512,  2,  2,  6,  2 }, /* index 179  */
340 { 9,  1,  0,  512,  8,  1,  3,  2 }, /* index 180  */
341 { 9,  1,  0,  512,  2,  1,  6,  2 }, /* index 181  */
342 { 9,  1,  0,  768,  2,  2,  6,  2 }, /* index 182  */
343 { 9,  1,  0,  528,  2,  1,  6,  2 }, /* index 183  */
344 { 9,  1,  0,  640,  8,  1,  3,  2 }, /* index 184  */
345 { 9,  1,  0,  792,  2,  1,  6,  2 }, /* index 185  */
346 { 9,  1,  0,  792,  2,  2,  6,  2 }, /* index 186  */
347 { 9,  1,  0,  682,  2,  1,  6,  2 }, /* index 187  */
348 { 9,  1,  0, 1023,  8,  1,  3,  2 }, /* index 188  */
349 {10, 16,  1,  512,  2,  2,  2,  6 }, /* index 189  */
350 {10,  8,  1,  512,  2,  2,  2,  6 }, /* index 190  */
351 {10,  4,  1,  512,  2,  1,  2,  6 }, /* index 191  */
352 {10,  2,  1,  512,  2,  1,  2,  6 }, /* index 192  */
353 {10,  2,  1,  768,  2,  2,  2,  6 }, /* index 193  */
354 {10,  2,  1,  640,  2,  1,  2,  6 }, /* index 194  */
355 {10,  2,  1,  640,  8,  1,  1,  6 }, /* index 195  */
356 {10,  2,  1,  528,  8,  1,  1,  6 }, /* index 196  */
357 {10,  2,  1,  528,  2,  2,  2,  6 }, /* index 197  */
358 {10,  2,  1,  924,  2,  1,  2,  6 }, /* index 198  */
359 {10,  8,  1,  512,  8,  2,  1,  6 }, /* index 199  */
360 {10,  4,  1,  512,  8,  1,  1,  6 }, /* index 200  */
361 {10,  1,  0,  512,  2,  2,  2,  6 }, /* index 201  */
362 {10,  1,  0,  512,  8,  1,  1,  6 }, /* index 202  */
363 {10,  1,  0,  512,  2,  1,  2,  6 }, /* index 203  */
364 {10,  1,  0,  768,  2,  2,  2,  6 }, /* index 204  */
365 {10,  1,  0,  528,  2,  1,  2,  6 }, /* index 205  */
366 {10,  1,  0,  640,  8,  1,  1,  6 }, /* index 206  */
367 {10,  1,  0,  792,  2,  1,  2,  6 }, /* index 207  */
368 {10,  1,  0,  792,  2,  2,  2,  6 }, /* index 208  */
369 {10,  1,  0,  682,  2,  1,  2,  6 }, /* index 209  */
370 {10,  1,  0, 1023,  8,  1,  1,  6 }, /* index 210  */
371 {11,  2,  1,  512,  2,  1,  6,  2 }, /* index 211  */
372 {11,  2,  1,  528,  8,  1,  3,  2 }, /* index 212  */
373 {11,  2,  1,  640,  8,  1,  3,  2 }, /* index 213  */
374 {11,  2,  1,  640,  2,  1,  6,  2 }, /* index 214  */
375 {11,  2,  1,  528,  2,  2,  6,  2 }, /* index 215  */
376 {11,  2,  1,  768,  2,  2,  6,  2 }, /* index 216  */
377 {11,  1,  0,  512,  2,  2,  6,  2 }, /* index 217  */
378 {11,  1,  0,  512,  8,  1,  3,  2 }, /* index 218  */
379 {11,  1,  0,  512,  2,  1,  6,  2 }, /* index 219  */
380 {11,  1,  0,  768,  2,  2,  6,  2 }, /* index 220  */
381 {11,  1,  0,  528,  2,  1,  6,  2 }, /* index 221  */
382 {11,  1,  0,  640,  8,  1,  3,  2 }, /* index 222  */
383 {11,  1,  0,  792,  2,  2,  6,  2 }, /* index 223  */
384 {11,  1,  0,  682,  2,  1,  6,  2 }, /* index 224  */
385 {11,  1,  0, 1023,  8,  1,  3,  2 }, /* index 225  */
386 {12,  2,  1,  512,  0,  1,  3,  4 }, /* index 226  */
387 {12,  2,  1,  528,  6,  1,  2,  4 }, /* index 227  */
388 {12,  2,  1,  640,  6,  1,  2,  4 }, /* index 228  */
389 {12,  2,  1,  528,  0,  2,  3,  4 }, /* index 229  */
390 {12,  2,  1,  768,  0,  2,  3,  4 }, /* index 230  */
391 {12,  1,  0,  512,  0,  2,  3,  4 }, /* index 231  */
392 {12,  1,  0,  512,  6,  1,  2,  4 }, /* index 232  */
393 {12,  1,  0,  512,  0,  1,  3,  4 }, /* index 233  */
394 {12,  1,  0,  768,  0,  2,  3,  4 }, /* index 234  */
395 {12,  1,  0,  528,  0,  1,  3,  4 }, /* index 235  */
396 {12,  1,  0,  640,  6,  1,  2,  4 }, /* index 236  */
397 {12,  1,  0,  792,  0,  1,  3,  4 }, /* index 237  */
398 {12,  1,  0,  792,  0,  2,  3,  4 }, /* index 238  */
399 {12,  1,  0,  682,  0,  1,  3,  4 }, /* index 239  */
400 {12,  1,  0, 1023,  6,  1,  2,  4 }, /* index 240  */
401 {13,  2,  1,  512,  0,  1,  2,  6 }, /* index 241  */
402 {13,  2,  1,  528,  2,  1,  2,  6 }, /* index 242  */
403 {13,  2,  1,  640,  0,  1,  2,  6 }, /* index 243  */
404 {13,  2,  1,  640,  2,  1,  2,  6 }, /* index 244  */
405 {13,  2,  1,  528,  0,  2,  2,  6 }, /* index 245  */
406 {13,  2,  1,  768,  0,  2,  2,  6 }, /* index 246  */
407 {13,  1,  0,  512,  0,  2,  2,  6 }, /* index 247  */
408 {13,  1,  0,  512,  2,  1,  2,  6 }, /* index 248  */
409 {13,  1,  0,  512,  0,  1,  2,  6 }, /* index 249  */
410 {13,  1,  0,  768,  0,  2,  2,  6 }, /* index 250  */
411 {13,  1,  0,  528,  0,  1,  2,  6 }, /* index 251  */
412 {13,  1,  0,  640,  2,  1,  2,  6 }, /* index 252  */
413 {13,  1,  0,  792,  0,  2,  2,  6 }, /* index 253  */
414 {13,  1,  0,  682,  0,  1,  2,  6 }, /* index 254  */
415 {13,  1,  0, 1023,  2,  1,  2,  6 }  /* index 255  */
416 };
417
418 #else
419 /* prach config index Table 6.3.3.2-2 spec 38.211 
420  * PRACH format given as follows:
421  * 0 = 0
422  * 1 = 1
423  * 2 = 2
424  * 3 = 3
425  * 4 = A1
426  * 5 = A2
427  * 6 = A3
428  * 7 = B1
429  * 8 = B4
430  * 9 = C0
431  * 10 = C2
432  * 11 = A1/B1
433  * 12 = A2/B2
434  * 13 = A3/B3 
435  * Subframe num is represented considering 0-9 bits and
436  * value 1 corresponds to the subframe that is valid 
437  */
438
439 uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8] = {
440 { 0, 16,  1,    2,  0,  0,  0,  0 }, /* index 0   */
441 { 0, 16,  1,   16,  0,  0,  0,  0 }, /* index 1   */
442 { 0, 16,  1,  128,  0,  0,  0,  0 }, /* index 2   */
443 { 0, 16,  1,  512,  0,  0,  0,  0 }, /* index 3   */
444 { 0,  8,  1,    2,  0,  0,  0,  0 }, /* index 4   */
445 { 0,  8,  1,   16,  0,  0,  0,  0 }, /* index 5   */
446 { 0,  8,  1,  128,  0,  0,  0,  0 }, /* index 6   */
447 { 0,  8,  1,  512,  0,  0,  0,  0 }, /* index 7   */
448 { 0,  4,  1,    2,  0,  0,  0,  0 }, /* index 8   */
449 { 0,  4,  1,   16,  0,  0,  0,  0 }, /* index 9   */
450 { 0,  4,  1,  128,  0,  0,  0,  0 }, /* index 10  */
451 { 0,  4,  1,  512,  0,  0,  0,  0 }, /* index 11  */
452 { 0,  2,  1,    2,  0,  0,  0,  0 }, /* index 12  */
453 { 0,  2,  1,   16,  0,  0,  0,  0 }, /* index 13  */
454 { 0,  2,  1,  128,  0,  0,  0,  0 }, /* index 14  */
455 { 0,  2,  1,  512,  0,  0,  0,  0 }, /* index 15  */
456 { 0,  1,  0,    2,  0,  0,  0,  0 }, /* index 16  */
457 { 0,  1,  0,   16,  0,  0,  0,  0 }, /* index 17  */
458 { 0,  1,  0,  128,  0,  0,  0,  0 }, /* index 18  */
459 { 0,  1,  0,   66,  0,  0,  0,  0 }, /* index 19  */
460 { 0,  1,  0,  132,  0,  0,  0,  0 }, /* index 20  */
461 { 0,  1,  0,  264,  0,  0,  0,  0 }, /* index 21  */
462 { 0,  1,  0,  146,  0,  0,  0,  0 }, /* index 22  */
463 { 0,  1,  0,  292,  0,  0,  0,  0 }, /* index 23  */
464 { 0,  1,  0,  584,  0,  0,  0,  0 }, /* index 24  */
465 { 0,  1,  0,  341,  0,  0,  0,  0 }, /* index 25  */
466 { 0,  1,  0,  682,  0,  0,  0,  0 }, /* index 26  */
467 { 0,  1,  0, 1023,  0,  0,  0,  0 }, /* index 27  */
468 { 1, 16,  1,    2,  0,  0,  0,  0 }, /* index 28  */
469 { 1, 16,  1,   16,  0,  0,  0,  0 }, /* index 29  */
470 { 1, 16,  1,  128,  0,  0,  0,  0 }, /* index 30  */
471 { 1, 16,  1,  512,  0,  0,  0,  0 }, /* index 31  */
472 { 1,  8,  1,    2,  0,  0,  0,  0 }, /* index 32  */
473 { 1,  8,  1,   16,  0,  0,  0,  0 }, /* index 33  */
474 { 1,  8,  1,  128,  0,  0,  0,  0 }, /* index 34  */
475 { 1,  8,  1,  512,  0,  0,  0,  0 }, /* index 35  */
476 { 1,  4,  1,    2,  0,  0,  0,  0 }, /* index 36  */
477 { 1,  4,  1,   16,  0,  0,  0,  0 }, /* index 37  */
478 { 1,  4,  1,  128,  0,  0,  0,  0 }, /* index 38  */
479 { 1,  4,  1,  512,  0,  0,  0,  0 }, /* index 39  */
480 { 1,  2,  1,    2,  0,  0,  0,  0 }, /* index 40  */
481 { 1,  2,  1,   16,  0,  0,  0,  0 }, /* index 41  */
482 { 1,  2,  1,  128,  0,  0,  0,  0 }, /* index 42  */
483 { 1,  2,  1,  512,  0,  0,  0,  0 }, /* index 43  */
484 { 1,  1,  0,    2,  0,  0,  0,  0 }, /* index 44  */
485 { 1,  1,  0,   16,  0,  0,  0,  0 }, /* index 45  */
486 { 1,  1,  0,  128,  0,  0,  0,  0 }, /* index 46  */
487 { 1,  1,  0,   64,  0,  0,  0,  0 }, /* index 47  */
488 { 1,  1,  0,  132,  0,  0,  0,  0 }, /* index 48  */
489 { 1,  1,  0,  264,  0,  0,  0,  0 }, /* index 49  */
490 { 1,  1,  0,  146,  0,  0,  0,  0 }, /* index 50  */
491 { 1,  1,  0,  292,  0,  0,  0,  0 }, /* index 51  */
492 { 1,  1,  0,  584,  0,  0,  0,  0 }, /* index 52  */
493 { 2, 16,  1,    2,  0,  0,  0,  0 }, /* index 53  */
494 { 2,  8,  1,    2,  0,  0,  0,  0 }, /* index 54  */
495 { 2,  4,  0,    2,  0,  0,  0,  0 }, /* index 55  */
496 { 2,  2,  0,    2,  0,  0,  0,  0 }, /* index 56  */
497 { 2,  2,  0,   32,  0,  0,  0,  0 }, /* index 57  */
498 { 2,  1,  0,    2,  0,  0,  0,  0 }, /* index 58  */
499 { 2,  1,  0,   32,  0,  0,  0,  0 }, /* index 59  */
500 { 3, 16,  1,    2,  0,  0,  0,  0 }, /* index 60  */
501 { 3, 16,  1,   16,  0,  0,  0,  0 }, /* index 61  */
502 { 3, 16,  1,  128,  0,  0,  0,  0 }, /* index 62  */
503 { 3, 16,  1,  512,  0,  0,  0,  0 }, /* index 63  */
504 { 3,  8,  1,    2,  0,  0,  0,  0 }, /* index 64  */
505 { 3,  8,  1,   16,  0,  0,  0,  0 }, /* index 65  */
506 { 3,  8,  1,  128,  0,  0,  0,  0 }, /* index 66  */
507 { 3,  4,  1,    2,  0,  0,  0,  0 }, /* index 67  */
508 { 3,  4,  1,   16,  0,  0,  0,  0 }, /* index 68  */
509 { 3,  4,  1,  128,  0,  0,  0,  0 }, /* index 69  */
510 { 3,  4,  1,  512,  0,  0,  0,  0 }, /* index 70  */
511 { 3,  2,  1,    2,  0,  0,  0,  0 }, /* index 71  */
512 { 3,  2,  1,   16,  0,  0,  0,  0 }, /* index 72  */
513 { 3,  2,  1,  128,  0,  0,  0,  0 }, /* index 73  */
514 { 3,  2,  1,  512,  0,  0,  0,  0 }, /* index 74  */
515 { 3,  1,  0,    2,  0,  0,  0,  0 }, /* index 75  */
516 { 3,  1,  0,   16,  0,  0,  0,  0 }, /* index 76  */
517 { 3,  1,  0,  128,  0,  0,  0,  0 }, /* index 77  */
518 { 3,  1,  0,   66,  0,  0,  0,  0 }, /* index 78  */
519 { 3,  1,  0,  132,  0,  0,  0,  0 }, /* index 79  */
520 { 3,  1,  0,  264,  0,  0,  0,  0 }, /* index 80  */
521 { 3,  1,  0,  146,  0,  0,  0,  0 }, /* index 81  */
522 { 3,  1,  0,  292,  0,  0,  0,  0 }, /* index 82  */
523 { 3,  1,  0,  584,  0,  0,  0,  0 }, /* index 83  */
524 { 3,  1,  0,  341,  0,  0,  0,  0 }, /* index 84  */
525 { 3,  1,  0,  682,  0,  0,  0,  0 }, /* index 85  */
526 { 3,  1,  0, 1023,  0,  0,  0,  0 }, /* index 86  */
527 { 4, 16,  0,  528,  0,  1,  6,  2 }, /* index 87  */
528 { 4, 16,  1,   16,  0,  2,  6,  2 }, /* index 88  */
529 { 4,  8,  0,  528,  0,  1,  6,  2 }, /* index 89  */
530 { 4,  8,  1,   16,  0,  2,  6,  2 }, /* index 90  */
531 { 4,  4,  0,  528,  0,  1,  6,  2 }, /* index 91  */
532 { 4,  4,  1,  528,  0,  1,  6,  2 }, /* index 92  */
533 { 4,  4,  0,   16,  0,  2,  6,  2 }, /* index 93  */
534 { 4,  2,  0,  528,  0,  1,  6,  2 }, /* index 94  */
535 { 4,  2,  0,    2,  0,  2,  6,  2 }, /* index 95  */
536 { 4,  2,  0,   16,  0,  2,  6,  2 }, /* index 96  */
537 { 4,  2,  0,  128,  0,  2,  6,  2 }, /* index 97  */
538 { 4,  1,  0,   16,  0,  1,  6,  2 }, /* index 98  */
539 { 4,  1,  0,   66,  0,  1,  6,  2 }, /* index 99  */
540 { 4,  1,  0,  528,  0,  1,  6,  2 }, /* index 100  */
541 { 4,  1,  0,    2,  0,  2,  6,  2 }, /* index 101  */
542 { 4,  1,  0,  128,  0,  2,  6,  2 }, /* index 102  */
543 { 4,  1,  0,  132,  0,  2,  6,  2 }, /* index 103  */
544 { 4,  1,  0,  146,  0,  2,  6,  2 }, /* index 104  */
545 { 4,  1,  0,  341,  0,  2,  6,  2 }, /* index 105  */
546 { 4,  1,  0, 1023,  0,  2,  6,  2 }, /* index 106  */
547 { 4,  1,  0,  682,  0,  2,  6,  2 }, /* index 107  */
548 {11,  2,  0,  528,  0,  1,  7,  2 }, /* index 108  */
549 {11,  2,  0,   16,  0,  2,  7,  2 }, /* index 109  */
550 {11,  1,  0,   16,  0,  1,  7,  2 }, /* index 110  */
551 {11,  1,  0,   66,  0,  1,  7,  2 }, /* index 111  */
552 {11,  1,  0,  528,  0,  1,  7,  2 }, /* index 112  */
553 {11,  1,  0,    2,  0,  2,  7,  2 }, /* index 113  */
554 {11,  1,  0,  128,  0,  2,  7,  2 }, /* index 114  */
555 {11,  1,  0,  146,  0,  2,  7,  2 }, /* index 115  */
556 {11,  1,  0,  341,  0,  2,  7,  2 }, /* index 116  */
557 { 5, 16,  1,  580,  0,  1,  3,  4 }, /* index 117  */
558 { 5, 16,  1,   16,  0,  2,  3,  4 }, /* index 118  */
559 { 5,  8,  1,  580,  0,  1,  3,  4 }, /* index 119  */
560 { 5,  8,  1,   16,  0,  2,  3,  4 }, /* index 120  */
561 { 5,  4,  0,  580,  0,  1,  3,  4 }, /* index 121  */
562 { 5,  4,  0,   16,  0,  2,  3,  4 }, /* index 122  */
563 { 5,  2,  1,  580,  0,  1,  3,  4 }, /* index 123  */
564 { 5,  2,  0,    2,  0,  2,  3,  4 }, /* index 124  */
565 { 5,  2,  0,   16,  0,  2,  3,  4 }, /* index 125  */
566 { 5,  2,  0,  128,  0,  2,  3,  4 }, /* index 126  */
567 { 5,  1,  0,   16,  0,  1,  3,  4 }, /* index 127  */
568 { 5,  1,  0,   66,  0,  1,  3,  4 }, /* index 128  */
569 { 5,  1,  0,  528,  0,  1,  3,  4 }, /* index 129  */
570 { 5,  1,  0,    2,  0,  2,  3,  4 }, /* index 130  */
571 { 5,  1,  0,  128,  0,  2,  3,  4 }, /* index 131  */
572 { 5,  1,  0,  132,  0,  2,  3,  4 }, /* index 132  */
573 { 5,  1,  0,  146,  0,  2,  3,  4 }, /* index 133  */
574 { 5,  1,  0,  341,  0,  2,  3,  4 }, /* index 134  */
575 { 5,  1,  0, 1023,  0,  2,  3,  4 }, /* index 135  */
576 { 5,  1,  0,  682,  0,  2,  3,  4 }, /* index 136  */
577 {12,  2,  1,  580,  0,  1,  3,  4 }, /* index 137  */
578 {12,  2,  0,   16,  0,  2,  3,  4 }, /* index 138  */
579 {12,  1,  0,   16,  0,  1,  3,  4 }, /* index 139  */
580 {12,  1,  0,   66,  0,  1,  3,  4 }, /* index 140  */
581 {12,  1,  0,  528,  0,  1,  3,  4 }, /* index 141  */
582 {12,  1,  0,    2,  0,  2,  3,  4 }, /* index 142  */
583 {12,  1,  0,  128,  0,  2,  3,  4 }, /* index 143  */
584 {12,  1,  0,  146,  0,  2,  3,  4 }, /* index 144  */
585 {12,  1,  0,  341,  0,  2,  3,  4 }, /* index 145  */
586 {12,  1,  0, 1023,  0,  2,  3,  4 }, /* index 146  */
587 { 6, 16,  1,  528,  0,  1,  2,  6 }, /* index 147  */
588 { 6, 16,  1,   16,  0,  2,  2,  6 }, /* index 148  */
589 { 6,  8,  1,  528,  0,  1,  2,  6 }, /* index 149  */
590 { 6,  8,  1,   16,  0,  2,  2,  6 }, /* index 150  */
591 { 6,  4,  0,  528,  0,  1,  2,  6 }, /* index 151  */
592 { 6,  4,  0,   16,  0,  2,  2,  6 }, /* index 152  */
593 { 6,  2,  1,  580,  0,  2,  2,  6 }, /* index 153  */
594 { 6,  2,  0,    2,  0,  2,  2,  6 }, /* index 154  */
595 { 6,  2,  0,   16,  0,  2,  2,  6 }, /* index 155  */
596 { 6,  2,  0,  128,  0,  2,  2,  6 }, /* index 156  */
597 { 6,  1,  0,   16,  0,  1,  2,  6 }, /* index 157  */
598 { 6,  1,  0,   66,  0,  1,  2,  6 }, /* index 158  */
599 { 6,  1,  0,  528,  0,  1,  2,  6 }, /* index 159  */
600 { 6,  1,  0,    2,  0,  2,  2,  6 }, /* index 160  */
601 { 6,  1,  0,  128,  0,  2,  2,  6 }, /* index 161  */
602 { 6,  1,  0,  132,  0,  2,  2,  6 }, /* index 162  */
603 { 6,  1,  0,  146,  0,  2,  2,  6 }, /* index 163  */
604 { 6,  1,  0,  341,  0,  2,  2,  6 }, /* index 164  */
605 { 6,  1,  0, 1023,  0,  2,  2,  6 }, /* index 165  */
606 { 6,  1,  0,  682,  0,  2,  2,  6 }, /* index 166  */
607 {13,  2,  1,  580,  0,  2,  2,  6 }, /* index 167  */
608 {13,  2,  0,   16,  0,  2,  2,  6 }, /* index 168  */
609 {13,  1,  0,   16,  0,  1,  2,  6 }, /* index 169  */
610 {13,  1,  0,   66,  0,  1,  2,  6 }, /* index 170  */
611 {13,  1,  0,  528,  0,  1,  2,  6 }, /* index 171  */
612 {13,  1,  0,    2,  0,  2,  2,  6 }, /* index 172  */
613 {13,  1,  0,  128,  0,  2,  2,  6 }, /* index 173  */
614 {13,  1,  0,  146,  0,  2,  2,  6 }, /* index 174  */
615 {13,  1,  0,  341,  0,  2,  2,  6 }, /* index 175  */
616 {13,  1,  0, 1023,  0,  2,  2,  6 }, /* index 176  */
617 { 7, 16,  0,  528,  0,  1,  7,  2 }, /* index 177  */
618 { 7, 16,  1,   16,  0,  2,  7,  2 }, /* index 178  */
619 { 7,  8,  0,  528,  0,  1,  7,  2 }, /* index 179  */
620 { 7,  8,  1,   16,  0,  2,  7,  2 }, /* index 180  */
621 { 7,  4,  0,  528,  0,  1,  7,  2 }, /* index 181  */
622 { 7,  4,  1,  528,  0,  1,  7,  2 }, /* index 182  */
623 { 7,  4,  0,   16,  0,  2,  7,  2 }, /* index 183  */
624 { 7,  2,  0,  528,  0,  1,  7,  2 }, /* index 184  */
625 { 7,  2,  0,    2,  0,  2,  7,  2 }, /* index 185  */
626 { 7,  2,  0,   16,  0,  2,  7,  2 }, /* index 186  */
627 { 7,  2,  0,  128,  0,  2,  7,  2 }, /* index 187  */
628 { 7,  1,  0,   16,  0,  1,  7,  2 }, /* index 188  */
629 { 7,  1,  0,   66,  0,  1,  7,  2 }, /* index 189  */
630 { 7,  1,  0,  528,  0,  1,  7,  2 }, /* index 190  */
631 { 7,  1,  0,    2,  0,  2,  7,  2 }, /* index 191  */
632 { 7,  1,  0,  128,  0,  2,  7,  2 }, /* index 192  */
633 { 7,  1,  0,  132,  0,  2,  7,  2 }, /* index 193  */
634 { 7,  1,  0,  146,  0,  2,  7,  2 }, /* index 194  */
635 { 7,  1,  0,  341,  0,  2,  7,  2 }, /* index 195  */
636 { 7,  1,  0, 1023,  0,  2,  7,  2 }, /* index 196  */
637 { 7,  1,  0,  682,  0,  2,  7,  2 }, /* index 197  */
638 { 8, 16,  0,  528,  0,  2,  1, 12 }, /* index 198  */
639 { 8, 16,  1,   16,  0,  2,  1, 12 }, /* index 199  */
640 { 8,  8,  0,  528,  0,  2,  1, 12 }, /* index 200  */
641 { 8,  8,  1,   16,  0,  2,  1, 12 }, /* index 201  */
642 { 8,  4,  0,  528,  0,  2,  1, 12 }, /* index 202  */
643 { 8,  4,  0,   16,  0,  2,  1, 12 }, /* index 203  */
644 { 8,  4,  1,  528,  0,  2,  1, 12 }, /* index 204  */
645 { 8,  2,  0,  528,  0,  2,  1, 12 }, /* index 205  */
646 { 8,  2,  0,    2,  0,  2,  1, 12 }, /* index 206  */
647 { 8,  2,  0,   16,  0,  2,  1, 12 }, /* index 207  */
648 { 8,  2,  0,  128,  0,  2,  1, 12 }, /* index 208  */
649 { 8,  1,  0,    2,  0,  2,  1, 12 }, /* index 209  */
650 { 8,  1,  0,   16,  0,  2,  1, 12 }, /* index 210  */
651 { 8,  1,  0,  128,  0,  2,  1, 12 }, /* index 211  */
652 { 8,  1,  0,   66,  0,  2,  1, 12 }, /* index 212  */
653 { 8,  1,  0,  132,  0,  2,  1, 12 }, /* index 213  */
654 { 8,  1,  0,  528,  0,  2,  1, 12 }, /* index 214  */
655 { 8,  1,  0,  146,  0,  2,  1, 12 }, /* index 215  */
656 { 8,  1,  0,  341,  0,  2,  1, 12 }, /* index 216  */
657 { 8,  1,  0, 1023,  0,  2,  1, 12 }, /* index 217  */
658 { 8,  1,  0,  682,  0,  2,  1, 12 }, /* index 218  */
659 { 9,  8,  1,   16,  0,  2,  7,  2 }, /* index 219  */
660 { 9,  4,  1,  528,  0,  1,  7,  2 }, /* index 220  */
661 { 9,  4,  0,   16,  0,  2,  7,  2 }, /* index 221  */
662 { 9,  2,  0,  528,  0,  1,  7,  2 }, /* index 222  */
663 { 9,  2,  0,    2,  0,  2,  7,  2 }, /* index 223  */
664 { 9,  2,  0,   16,  0,  2,  7,  2 }, /* index 224  */
665 { 9,  2,  0,  128,  0,  2,  7,  2 }, /* index 225  */
666 { 9,  1,  0,   16,  0,  1,  7,  2 }, /* index 226  */
667 { 9,  1,  0,   66,  0,  1,  7,  2 }, /* index 227  */
668 { 9,  1,  0,  528,  0,  1,  7,  2 }, /* index 228  */
669 { 9,  1,  0,    2,  0,  2,  7,  2 }, /* index 229  */
670 { 9,  1,  0,  128,  0,  2,  7,  2 }, /* index 230  */
671 { 9,  1,  0,  132,  0,  2,  7,  2 }, /* index 231  */
672 { 9,  1,  0,  146,  0,  2,  7,  2 }, /* index 232  */
673 { 9,  1,  0,  341,  0,  2,  7,  2 }, /* index 233  */
674 { 9,  1,  0, 1023,  0,  2,  7,  2 }, /* index 234  */
675 { 9,  1,  0,  682,  0,  2,  7,  2 }, /* index 235  */
676 {10, 16,  1,  528,  0,  1,  2,  6 }, /* index 236  */
677 {10, 16,  1,   16,  0,  2,  2,  6 }, /* index 237  */
678 {10,  8,  1,  528,  0,  1,  2,  6 }, /* index 238  */
679 {10,  8,  1,   16,  0,  2,  2,  6 }, /* index 239  */
680 {10,  4,  0,  528,  0,  1,  2,  6 }, /* index 240  */
681 {10,  4,  0,   16,  0,  2,  2,  6 }, /* index 241  */
682 {10,  2,  1,  580,  0,  2,  2,  6 }, /* index 242  */
683 {10,  2,  0,    2,  0,  2,  2,  6 }, /* index 243  */
684 {10,  2,  0,   16,  0,  2,  2,  6 }, /* index 244  */
685 {10,  2,  0,  128,  0,  2,  2,  6 }, /* index 245  */
686 {10,  1,  0,   16,  0,  1,  2,  6 }, /* index 246  */
687 {10,  1,  0,   66,  0,  1,  2,  6 }, /* index 247  */
688 {10,  1,  0,  528,  0,  1,  2,  6 }, /* index 248  */
689 {10,  1,  0,    2,  0,  2,  2,  6 }, /* index 249  */
690 {10,  1,  0,  128,  0,  2,  2,  6 }, /* index 250  */
691 {10,  1,  0,  132,  0,  2,  2,  6 }, /* index 251  */
692 {10,  1,  0,  146,  0,  2,  2,  6 }, /* index 252  */
693 {10,  1,  0,  341,  0,  2,  2,  6 }, /* index 253  */
694 {10,  1,  0, 1023,  0,  2,  2,  6 }, /* index 254  */
695 {10,  1,  0,  682,  0,  2,  2,  6 }  /* index 255  */
696 };
697 #endif
698
699 /* Defintion of delta value Table 6.1.2.1.1-5 spec 38.214 */
700 uint8_t puschDeltaTable[MAX_MU_PUSCH] = { 2, 3, 4, 6 };
701
702 uint16_t tbSizeTable[TOTAL_TBSIZE_VALUES] = {
703          24,    32,    40,    48,    56,    64,    72,    80,    88,    96, \
704         104,   112,   120,   128,   136,   144,   152,   160,   168,   176, \
705         184,   192,   208,   224,   240,   256,   272,   288,   304,   320, \
706         336,   352,   368,   384,   408,   432,   456,   480,   504,   528, \
707         552,   576,   608,   640,   672,   704,   736,   768,   808,   848, \
708         888,   928,   984,  1032,  1064,  1128,  1160,  1192,  1224,  1256, \
709        1288,  1320,  1352,  1416,  1480,  1544,  1608,  1672,  1736,  1800, \
710        1864,  1928,  2024,  2088,  2152,  2216,  2280,  2408,  2472,  2536, \
711        2600,  2664,  2728,  2792,  2856,  2976,  3104,  3240,  3368,  3496, \
712        3624,  3752,  3824 };
713
714 uint16_t mcsTable[32][3] = {
715       {   0,   2,   120},   /* mcs index  0 */ 
716       {   1,   2,   157},   /* mcs index  1 */ 
717       {   2,   2,   193},   /* mcs index  2 */ 
718       {   3,   2,   251},   /* mcs index  3 */ 
719       {   4,   2,   308},   /* mcs index  4 */ 
720       {   5,   2,   379},   /* mcs index  5 */ 
721       {   6,   2,   449},   /* mcs index  6 */ 
722       {   7,   2,   526},   /* mcs index  7 */ 
723       {   8,   2,   602},   /* mcs index  8 */ 
724       {   9,   2,   679},   /* mcs index  9 */ 
725       {  10,   4,   340},   /* mcs index 10 */ 
726       {  11,   4,   378},   /* mcs index 11 */ 
727       {  12,   4,   434},   /* mcs index 12 */ 
728       {  13,   4,   490},   /* mcs index 13 */ 
729       {  14,   4,   553},   /* mcs index 14 */ 
730       {  15,   4,   616},   /* mcs index 15 */
731       {  16,   4,   658},   /* mcs index 16 */
732       {  17,   6,   438},   /* mcs index 17 */
733       {  18,   6,   466},   /* mcs index 18 */
734       {  19,   6,   517},   /* mcs index 19 */
735       {  20,   6,   567},   /* mcs index 20 */
736       {  21,   6,   616},   /* mcs index 21 */
737       {  22,   6,   666},   /* mcs index 22 */
738       {  23,   6,   719},   /* mcs index 23 */
739       {  24,   6,   772},   /* mcs index 24 */
740       {  25,   6,   822},   /* mcs index 25 */
741       {  26,   6,   873},   /* mcs index 26 */
742       {  27,   6,   910},   /* mcs index 27 */
743       {  28,   6,   948},   /* mcs index 28 */
744       {  29,   2,     0},   /* mcs index 29 */
745       {  30,   4,     0},   /* mcs index 30 */
746       {  31,   6,     0}};  /* mcs index 31 */
747
748 /* PUCCH resource sets before dedicated PUCCH resource configuration */
749 /* Table 9.2.1-1 spec 38.213      */
750 /*{PUCCH_Format, 1stSym, NumSym, PRBOffset, Num_CyclicShift}*/
751 uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][5] = {
752 { 0,  12,  2,  0,  2 }, /* index  0 */
753 { 0,  12,  2,  0,  3 }, /* index  1 */
754 { 0,  12,  2,  3,  3 }, /* index  2 */
755 { 1,  10,  4,  0,  2 }, /* index  3 */
756 { 1,  10,  4,  0,  4 }, /* index  4 */
757 { 1,  10,  4,  2,  4 }, /* index  5 */
758 { 1,  10,  4,  4,  4 }, /* index  6 */
759 { 1,   4, 10,  0,  2 }, /* index  7 */
760 { 1,   4, 10,  0,  4 }, /* index  8 */
761 { 1,   4, 10,  2,  4 }, /* index  9 */
762 { 1,   4, 10,  4,  4 }, /* index 10 */
763 { 1,   0, 14,  0,  2 }, /* index 11 */
764 { 1,   0, 14,  0,  4 }, /* index 12 */
765 { 1,   0, 14,  2,  4 }, /* index 13 */
766 { 1,   0, 14,  4,  4 }, /* index 14 */
767 { 1,   0, 14,  (MAX_NUM_RB/4),  4 }, /* index 15 */
768 };
769
770 /*CQI Table From Spec 38.214 Table 5.2.2.1-2
771  * {Modulation Scheme, CodeRate, Efficiency(bits per symbol)}
772  * Modulation Scheme is numbered based on bit rate as follows
773  * QPSK = 2, 16QAM = 4, 64QAM = 6
774  * */
775 float cqiTable1[MAX_NUM_CQI_IDX][3] = {
776 { 0, 0, 0},        /*index 0*/
777 { 2, 78, 0.1523},  /*index 1*/
778 { 2, 120, 0.2344}, /*index 2*/
779 { 2, 193, 0.3770}, /*index 3*/
780 { 2, 308, 0.6016}, /*index 4*/
781 { 2, 449, 0.8770}, /*index 5*/
782 { 2, 602, 1.1758}, /*index 6*/
783 { 4, 378, 1.4766}, /*index 7*/
784 { 4, 490, 1.9141}, /*index 8*/
785 { 4, 616, 2.4063}, /*index 9*/
786 { 6, 466, 2.7305}, /*index 10*/
787 { 6, 567, 3.3223}, /*index 11*/
788 { 6, 666, 3.9023}, /*index 12*/
789 { 6, 772, 4.5234}, /*index 13*/
790 { 6, 873, 5.1152}, /*index 14*/
791 { 6, 948, 5.5547}, /*index 15*/
792 };
793
794 /*As per Spec 38.211 Table 7.3.2.1-1, using number of CCE per AggLevel 
795  * Num of RE for Agg Level = numCCEPerAggLevel * (6 REG) * (12 Subcarriers)
796  */
797 uint16_t totalRE_PerAggLevel[MAX_NUM_AGG_LVL]= {72, 144, 288, 576, 1152};
798
799
800 /* Minimum Msg3 scheduling time should be calculated based on N1+N2+NTAmax+0.5
801  * ms formula.
802  * Refer spec 38.213 section 8.3.
803  * Harcoding the minimum msg3 scheduling for now */
804 uint8_t minMsg3SchTime[MAX_NUM_MU] = {6, 6, 6, 6};
805
806 uint8_t defaultUlAckTbl[DEFAULT_UL_ACK_LIST_COUNT]= {1, 2, 3 , 4, 5, 6, 7, 8};
807
808 uint8_t schCmnDlRvTbl[4] = {0, 2, 3, 1};
809 /**
810  * @brief Function to find first DMRS symbol in PDSCH
811  *
812  * @details
813  *
814  *     Function: findDmrsStartSymbol
815  *
816  *     This function finds first DMRS symbol using DMRS symbol 
817  *     position bitmap.
818  *
819  *  @param[in]  DMRS symbol position bitmap
820  *  @return     Success : First DRMS symbol
821  *              Failure : MAX_SYMB_PER_SLOT 
822  **/
823 uint8_t findDmrsStartSymbol(uint16_t dlDmrsSymbBitMap)
824 {
825    uint8_t position = 0;
826    uint16_t mask = 1;
827
828    while(position < MAX_SYMB_PER_SLOT)
829    {
830       if(dlDmrsSymbBitMap & mask)
831          break;  
832       mask = mask << 1;
833       position++;
834    }
835    return position;   
836 }
837
838 /**
839  * @brief Function to add a node to a linked list
840  *
841  * @details
842  *
843  *     Function: addNodeToLList
844  *
845  *     This function adds a new node to the linked list
846  *
847  *  @param[in]  Pointer to the list
848  *              Pointer to node to be added
849  *              Pointer to current node
850  *  @return     ROK
851  *              RFAILED
852  **/
853 uint8_t addNodeToLList(CmLListCp *llist, void *blockToAdd, CmLList *currNode)
854 {
855    CmLList  *newNode;
856
857    SCH_ALLOC(newNode, sizeof(CmLList));
858    if(newNode)
859    {
860       newNode->node = (PTR)blockToAdd;
861       
862       if(currNode == NULLP)
863          cmLListAdd2Tail(llist, newNode);
864       else
865       {
866          llist->crnt = currNode;
867          cmLListInsAfterCrnt(llist, newNode);
868       }
869       return ROK;
870    } 
871    return RFAILED;
872 }
873
874 /**
875  * @brief Function to delete a node from linked list
876  *
877  * @details
878  *
879  *     Function: deleteNodeFromLList
880  *
881  *     This function deletes a node from the linked list
882  *
883  *  @param[in]  Pointer to the list
884  *              Pointer to node to be deleted
885  *  @return     Pointer to the deleted node
886  **/
887 uint8_t deleteNodeFromLList(CmLListCp *llist, CmLList *node)
888 {
889    node = cmLListDelFrm(llist, node);
890    SCH_FREE(node, sizeof(CmLList));
891
892    return ROK;
893 }
894
895 /**
896  * @brief Checks if requested PRBs are free
897  *
898  * @details
899  *
900  *     Function: isPrbAvailable
901  *
902  *     This functions loops through all free PRB blocks and 
903  *     checks if request PRB block is available for allocation
904  *
905  *  @param[in]  List of free PRB blocks
906  *              First PRB requested
907  *              Total number of PRB requested
908  *
909  *  @return     Returns Pointer to free block
910  *              NULL
911  **/
912 CmLList* isPrbAvailable(CmLListCp *freePrbBlockList, uint16_t startPrb, uint16_t numPrb)
913 {
914    uint16_t      endPrb = 0;
915    CmLList       *node = NULLP;
916    FreePrbBlock  *freeBlock = NULLP;
917
918    endPrb = startPrb + numPrb - 1; 
919
920    /* Iterate through all blocks of free PRB to check if requested PRBs can be assigned */
921    node = freePrbBlockList->first;
922    while(node)
923    {
924       freeBlock = (FreePrbBlock *)node->node;
925
926       /* Check if requested number of blocks can be allocated from the current block */
927       if(freeBlock->numFreePrb < numPrb)
928       {
929          DU_LOG("\nINFO   --> SCH: In isPrbAvailable, numFreePrb:%d is less than reqPrb:%d", freeBlock->numFreePrb, numPrb);
930          node = node->next;
931          continue;
932       }
933       
934       /* Check if requested PRBs belong within the range of current free block */
935       if(((startPrb >= freeBlock->startPrb) && (startPrb <= freeBlock->endPrb)) && \
936          ((endPrb >= freeBlock->startPrb) && (endPrb <= freeBlock->endPrb)))
937       {
938          return node;
939       }
940
941       /* If current block is unable to provide resources, check the next block */
942       node = node->next;
943    }
944    return NULLP;
945 }
946
947 /**
948  * @brief Function to update free PRB list
949  *
950  * @details
951  *
952  *     Function: removeAllocatedPrbFromFreePrbList
953  *
954  *     This function removes the allocated PRBs from the
955  *     list of free PRBs
956  *
957  *  @param[in]  Pointer to the list
958  *              Pointer to node from which PRB was allocated
959  *              Start PRB allocated
960  *              Number of PRBs allocated
961  *  @return     void
962  **/
963 void removeAllocatedPrbFromFreePrbList(CmLListCp *freePrbBlockList, CmLList *node, uint16_t startPrb, uint16_t numPrb)
964 {
965    uint16_t      endPrb;
966    FreePrbBlock  *newBlock = NULLP;
967    FreePrbBlock  *freeBlock = (FreePrbBlock *)node->node;
968
969    if(!node) 
970       return;
971    
972    endPrb = startPrb + numPrb -1;
973
974    /* If the whole block is allocated, remove it from linked list */
975    if(freeBlock->numFreePrb == numPrb)
976    {
977       if(deleteNodeFromLList(freePrbBlockList, node) == ROK)
978          SCH_FREE(freeBlock, sizeof(FreePrbBlock));
979    }
980
981    /* If PRB is allocated from start of free block, move the start of free block
982     * after last alloctaed PRB */
983    else if(freeBlock->startPrb == startPrb)
984    {
985       freeBlock->startPrb = endPrb+1;
986       freeBlock->numFreePrb = freeBlock->endPrb - freeBlock->startPrb +1;
987    }
988
989    /* If PRB is allocated from end of free block, move the end of free block
990     * before the first allocated PRB */
991    else if(freeBlock->endPrb == endPrb)
992    {
993       freeBlock->endPrb = startPrb-1;
994       freeBlock->numFreePrb = freeBlock->endPrb - freeBlock->startPrb +1;
995    }
996
997    /* If PRBs are allocated somewhere in between the free block, split it into 2
998     * nodes. Fist node contains free PRBs after the allocated PRBs. Second node
999     * contains free PRBs present before the allocated PRBs */
1000    else
1001    {
1002       /* Block 2 */
1003       SCH_ALLOC(newBlock, sizeof(FreePrbBlock));
1004       if(newBlock)
1005       {
1006          newBlock->startPrb = freeBlock->startPrb;
1007          newBlock->endPrb = startPrb-1;
1008          newBlock->numFreePrb = newBlock->endPrb - newBlock->startPrb +1;
1009          addNodeToLList(freePrbBlockList, newBlock, node);
1010       }
1011
1012       /* Block 1 */
1013       freeBlock->startPrb = endPrb+1;
1014       freeBlock->numFreePrb = freeBlock->endPrb - freeBlock->startPrb +1;
1015    }
1016 }
1017
1018 /**
1019  * @brief frequency domain allocation function. 
1020  *
1021  * @details
1022  *
1023  *     Function: schCalcTbSize
1024  *     
1025  *     This function finds the TBSize from table Table 5.1.3.2-1 spec 38.214
1026  *     
1027  *  @param[in]  payLoadSize - size of payload in bytes
1028  *  @return     TBsize from the Table in bytes
1029  **/
1030 uint16_t schCalcTbSize(uint32_t payLoadSize)
1031 {
1032    uint8_t tbsIndex = 0;
1033    uint16_t maxTbSize;
1034
1035    maxTbSize = tbSizeTable[TOTAL_TBSIZE_VALUES -1]/8;
1036    if(payLoadSize >= maxTbSize)
1037       return maxTbSize;
1038
1039    payLoadSize = payLoadSize*8;
1040    while(payLoadSize > tbSizeTable[tbsIndex])
1041    {
1042       tbsIndex++;
1043    }
1044
1045    /* return the TBsize in bytes */
1046    return (tbSizeTable[tbsIndex]/8);
1047 }
1048
1049 /**
1050  * @brief frequency domain allocation function. 
1051  *
1052  * @details
1053  *
1054  *     Function: schCalcNumPrb
1055  *     
1056  *     This function calculates the number of PRbs 
1057  *     
1058  *  @param[in]  tbSize in bytes
1059  *  @param[in]  mcs
1060  *  @param[in]  number of symbols
1061  *  @return   number PRBs
1062  **/
1063 uint16_t schCalcNumPrb(uint16_t tbSize, uint16_t mcs, uint8_t numSymbols)
1064 {
1065    uint16_t numPrb = 0;
1066    uint16_t nre = 0;
1067    uint16_t nreDash = 0;
1068    uint8_t  qm     = mcsTable[mcs][1];
1069    uint16_t rValue = mcsTable[mcs][2];
1070    uint8_t  numLayer = 1;       /* v value */
1071    uint8_t  numDmrsRePerPrb = 12;
1072
1073    tbSize = tbSize * 8; //Calculate tbSize in bits
1074
1075    /* formula used for calculation of rbSize, 38.214 section 5.1.3.2 *
1076     * Ninfo = S . Nre . R . Qm . v                                       *
1077     * Nre' = Nsc . NsymPdsch - NdmrsSymb - Noh                       *
1078     * Nre = min(156,Nre') . nPrb                                     */
1079
1080    nre = ceil( (float)tbSize * 1024 / (qm * rValue * numLayer));
1081
1082    nreDash = ceil( (12 * numSymbols) - numDmrsRePerPrb - 0);
1083
1084    if (nreDash > 156)
1085       nreDash = 156;
1086
1087    numPrb = ceil((float)nre / nreDash);   
1088    return numPrb;
1089 }
1090
1091 /**
1092 * @brief calculation of transport block size.
1093 *
1094 * @details
1095 *
1096 *     Function: schCalcTbSizeFromNPrb
1097 *
1098 *     This function calculates the transport block size
1099 *
1100 *  @param[in]  nPrb is num PRB
1101 *  @param[in]  mcs
1102 *  @param[in]  number of symbols
1103 *  @return   tbSize
1104 **/
1105 uint16_t schCalcTbSizeFromNPrb(uint16_t numPrb, uint16_t mcs, uint8_t numSymbols)
1106 {   
1107    uint8_t  qm     = mcsTable[mcs][1];
1108    uint16_t rValue = mcsTable[mcs][2];
1109    uint16_t tbsIndex = 0;
1110    uint32_t tbSize = 0;
1111    uint32_t nre = 0;
1112    uint32_t nreDash = 0;
1113    uint32_t nInfo = 0;
1114    uint32_t n = 0;
1115    uint32_t nInfoDash = 0;
1116    uint32_t c = 0;
1117    const uint8_t  numLayer = 1;
1118    const uint16_t numRbSc = 12;
1119    const uint16_t numDmrsRes = 12;
1120    const uint16_t sf = 1;
1121 //   uint16_t numPrbOvrHead = 0;
1122    
1123   /* formula used for calculation of rbSize, 38.214 section 5.1.3.2  *
1124    * Ninfo = Nre . R . Qm . v   where [ NInfo is tbSize]             *
1125    * Nre' = Nsc . NsymPdsch - NdmrsSymb - Noh                        *
1126    * Nre = min(156,Nre') . nPrb                                      */
1127
1128    nreDash = MIN(156, ceil( (numRbSc * numSymbols) - numDmrsRes - 0));
1129    nre = nreDash * numPrb;
1130    nInfo = ceil(nre * qm * numLayer * rValue/(1024.0 * sf));
1131
1132    if(nInfo <= 3824)
1133    {
1134       n = MAX(3, (uint32_t)cmLog2(nInfo) - 6);
1135       nInfoDash = MAX(24, (1<<n)*(nInfo/(1<<n)));
1136       while(nInfoDash > tbSizeTable[tbsIndex])
1137       {
1138          tbsIndex++;
1139       }
1140       tbSize = tbSizeTable[tbsIndex];
1141    }
1142    else
1143    {
1144       n = (uint32_t)cmLog2(nInfo - 24) - 5;
1145       nInfoDash = MAX(3840, (1<<n)*ceil((nInfo - 24)/(1<<n)));
1146
1147       if(rValue<256)
1148       {
1149          c = ceil((nInfoDash + 24)/3816);
1150          tbSize = 8 * c * ceil((nInfoDash + 24)/(8 * c)) - 24;
1151       }
1152       else
1153       {
1154          if(nInfoDash > 8424)
1155          {
1156             c = ceil((nInfoDash + 24)/8424);
1157             tbSize = 8 * c * ceil((nInfoDash + 24)/(8 * c)) - 24;
1158          }
1159          else
1160          {
1161             tbSize = 8 * ceil((nInfoDash + 24)/(8)) - 24;
1162          }
1163       }
1164    }
1165    return tbSize;
1166 }
1167
1168 /**
1169  * @brief fetching ueCb from cellCb
1170  *
1171  * @details
1172  *
1173  *     Function: schGetUeCb
1174  *
1175  *     This function fetched UeCb based on crnti from cellCb
1176  *
1177  *  @param[in]  cellCb
1178  *  @param[in]  crnti
1179  *  @return     ueCb
1180  **/
1181 SchUeCb* schGetUeCb(SchCellCb *cellCb, uint16_t crnti)
1182 {
1183    uint16_t ueId;
1184    GET_UE_ID(crnti, ueId);
1185    return &(cellCb->ueCb[ueId -1]);
1186 }
1187
1188 /**
1189  * @brief initialize UL slot info
1190  *
1191  * @details
1192  *
1193  *     Function: schInitUlSlot
1194  *
1195  *     This function intializes UL slot of the cell
1196  *
1197  *  @param[in]  schUlSlotInfo
1198  *  @return     void
1199  **/
1200 void schInitUlSlot(SchUlSlotInfo *schUlSlotInfo)
1201 {
1202    uint8_t ueIdx = 0;
1203    CmLList *node = NULLP, *next = NULLP;
1204    FreePrbBlock *freeBlock;
1205
1206    /* Delete the old blocks */
1207    if(schUlSlotInfo->prbAlloc.freePrbBlockList.count)
1208    {
1209       node = schUlSlotInfo->prbAlloc.freePrbBlockList.first;
1210    }
1211    while(node)
1212    {
1213       next = node->next;
1214       freeBlock = (FreePrbBlock *)node->node;
1215       if(deleteNodeFromLList(&schUlSlotInfo->prbAlloc.freePrbBlockList, node) == ROK)
1216          SCH_FREE(freeBlock, sizeof(FreePrbBlock));
1217       node = next;
1218    }
1219
1220    /* Initilize UL Slot info and mark all PRBs as free */
1221    memset(schUlSlotInfo, 0, sizeof(SchUlSlotInfo));
1222    cmLListInit(&schUlSlotInfo->prbAlloc.freePrbBlockList);
1223    SCH_ALLOC(freeBlock, sizeof(FreePrbBlock));
1224    if(freeBlock)
1225    {
1226       freeBlock->numFreePrb = MAX_NUM_RB;
1227       freeBlock->startPrb = 0;
1228       freeBlock->endPrb = MAX_NUM_RB-1;
1229       addNodeToLList(&schUlSlotInfo->prbAlloc.freePrbBlockList, freeBlock, NULL);
1230    }
1231  
1232    for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
1233    {
1234       schUlSlotInfo->schPuschInfo[ueIdx] = NULLP;
1235    }
1236 }
1237
1238 /**
1239  * @brief initialize DL slot info
1240  *
1241  * @details
1242  *
1243  *     Function: schInitDlSlot
1244  *
1245  *     This function intializes DL slot of the cell
1246  *
1247  *  @param[in]  schDlSlotInfo
1248  *  @return     void
1249  **/
1250 void schInitDlSlot(SchDlSlotInfo *schDlSlotInfo)
1251 {
1252    CmLList *node = NULLP, *next = NULLP;
1253    FreePrbBlock *freeBlock;
1254
1255    /* Delete the old blocks */
1256    if(schDlSlotInfo->prbAlloc.freePrbBlockList.count)
1257       node = schDlSlotInfo->prbAlloc.freePrbBlockList.first;
1258    while(node)
1259    {
1260       next = node->next;
1261       freeBlock = (FreePrbBlock *)node->node;
1262       if(deleteNodeFromLList(&schDlSlotInfo->prbAlloc.freePrbBlockList, node) == ROK)
1263          SCH_FREE(freeBlock, sizeof(FreePrbBlock));
1264       node = next;
1265    }
1266
1267    /* Initilize DL Slot info and mark all PRBs as free */
1268    memset(schDlSlotInfo, 0, sizeof(SchDlSlotInfo));
1269    cmLListInit(&schDlSlotInfo->prbAlloc.freePrbBlockList);
1270    SCH_ALLOC(freeBlock, sizeof(FreePrbBlock));
1271    if(freeBlock)
1272    {
1273       freeBlock->numFreePrb = MAX_NUM_RB;
1274       freeBlock->startPrb = 0;
1275       freeBlock->endPrb = MAX_NUM_RB-1;
1276       addNodeToLList(&schDlSlotInfo->prbAlloc.freePrbBlockList, freeBlock, NULL);
1277    }
1278 }
1279
1280 /**
1281  * @brief Fill resource bit map
1282  *
1283  * @details
1284  *
1285  *     Function: fillPrbBitmap
1286  *
1287  *     This function updates bitMap to mark the allocated PRBs
1288  *
1289  *  @param[in]  schDlSlotInfo
1290  *  @return     void
1291  **/
1292 bool fillPrbBitmap(uint64_t *prbBitMap, uint16_t startPrb, uint16_t numPrb)
1293 {
1294    uint16_t bitMapIdx = 0;
1295    uint16_t offsetInFirstIdx = 0;
1296    uint32_t numBitsToSetInFirstIdx = 0;
1297    uint64_t mask = MASK_BIT64_ON;
1298    uint64_t bitmapBackup[PRB_BITMAP_MAX_IDX];
1299
1300    /* Store backup of the bitmap in order to roll back if PRB allocation fails */
1301    memcpy(bitmapBackup, prbBitMap, sizeof(bitmapBackup));
1302
1303    /* Calculate the bitmap idx and offset of bit in that idx, to start
1304     * allocating PRBs from */
1305    bitMapIdx = startPrb / PRB_BITMAP_IDX_LEN;
1306    offsetInFirstIdx = startPrb % PRB_BITMAP_IDX_LEN;
1307
1308    /* If number of PRBs allocated >= number of unset bits in first idx starting from offset bit
1309     * then set all bits in first idx starting from offset bit
1310     * else set bits equal to number of PRBs allocated
1311     */
1312    numBitsToSetInFirstIdx = \
1313       (numPrb >= (PRB_BITMAP_IDX_LEN-offsetInFirstIdx)) ? (PRB_BITMAP_IDX_LEN-offsetInFirstIdx) : numPrb;
1314
1315    mask = mask >> (PRB_BITMAP_IDX_LEN-numBitsToSetInFirstIdx);
1316    mask = mask<<offsetInFirstIdx;
1317
1318    /* If PRBs to be allocated are not already in use, mark these PRBs as allocated */
1319    if(!(prbBitMap[bitMapIdx] & mask))
1320    {
1321       prbBitMap[bitMapIdx] = prbBitMap[bitMapIdx] | mask;
1322
1323       bitMapIdx++;
1324       numPrb = numPrb - numBitsToSetInFirstIdx;
1325       /* Set all bits in a bitMapIdx until remaining numPrb is less than PRB_BITMAP_IDX_LEN */
1326       while(numPrb > PRB_BITMAP_IDX_LEN)
1327       {
1328          if(prbBitMap[bitMapIdx])
1329          {
1330             memcpy(prbBitMap, bitmapBackup, sizeof(bitmapBackup));
1331             return RFAILED;
1332          }
1333          prbBitMap[bitMapIdx] = MASK_BIT64_ON;
1334          bitMapIdx++;
1335          numPrb = numPrb - PRB_BITMAP_IDX_LEN;
1336       }
1337
1338       /* Set bits for the remaining PRBs */
1339       if(numPrb)
1340       {
1341          mask = MASK_BIT64_ON;
1342          mask = mask >> (PRB_BITMAP_IDX_LEN-numPrb);
1343          if(!(prbBitMap[bitMapIdx] & mask))
1344          {
1345             prbBitMap[bitMapIdx] = prbBitMap[bitMapIdx] | mask;
1346          }
1347          else
1348          {
1349             memcpy(prbBitMap, bitmapBackup, sizeof(bitmapBackup));
1350             return RFAILED;
1351          }
1352       }
1353    }
1354    else
1355    {
1356       return RFAILED;
1357    }
1358    
1359    return ROK;
1360 }
1361
1362
1363 /**************************************************************************
1364  *
1365  * @brief Update the LCID Node in LCLL as per ActionType
1366  *
1367  * @details
1368  *
1369  *    Function : handleLcLList
1370  *
1371  *    Functionality:
1372  *     Search LCID in LCLL or if not found, create,Delete, or return
1373  *     node for this LCID
1374  *
1375  * @params[in] I/P > lcLinkList pointer (LcInfo list)
1376  *             I/P > lcId
1377  *             I/P > ActionType (Create,Delete or Just search) 
1378  *
1379  * @return lcNode > Pointer to the Node for that LcInfo
1380  *         If NULLP, FATAL FAILURE
1381  *
1382  * ***********************************************************************/
1383 LcInfo* handleLcLList(CmLListCp *lcLL, uint8_t lcId, ActionTypeLL action)
1384 {
1385    CmLList  *node = NULLP;
1386    LcInfo *lcNode = NULLP;
1387    bool found = FALSE;
1388
1389    if(lcLL == NULLP)
1390    {
1391       DU_LOG("\nERROR  -->  SCH: LcList doesnt exist");
1392       return NULLP;
1393    }
1394    node = lcLL->first;
1395
1396    /*Traversing the LC LinkList*/
1397    while(node)
1398    {
1399       lcNode = (LcInfo *)node->node;
1400       if(lcNode->lcId == lcId)
1401       { 
1402          found = TRUE;
1403          break;
1404       }
1405       node = node->next;
1406    }//end of while
1407
1408    switch(action)
1409    {
1410       case SEARCH:
1411          {
1412             if(!found)
1413             {
1414                lcNode = NULLP;
1415             }
1416             return lcNode;
1417          }
1418
1419       case CREATE:
1420          {
1421             if(node != NULLP)
1422                return lcNode;
1423
1424             /*Need to add a new node for this LC*/
1425
1426             /*List is empty; Initialize the LL ControlPointer*/
1427             if(lcLL->count == 0)
1428             {
1429                cmLListInit(lcLL);
1430             }
1431
1432             lcNode = NULLP;
1433             /*Allocate the List*/
1434             SCH_ALLOC(lcNode, sizeof(LcInfo));
1435             if(lcNode)
1436             {
1437                lcNode->lcId = lcId;
1438                lcNode->reqBO = 0;
1439                lcNode->allocBO = 0;
1440                lcNode->allocPRB = 0;
1441             }
1442             else
1443             {
1444                DU_LOG("\nERROR  -->  SCH : Allocation of List failed,lcId:%d",lcId);
1445                return NULLP;
1446             }
1447
1448             if(addNodeToLList(lcLL, lcNode, NULLP) == RFAILED)
1449             {
1450                DU_LOG("\nERROR  -->  SCH : failed to Add Node,lcId:%d",lcId);
1451                SCH_FREE(lcNode, sizeof(LcInfo));
1452                return NULLP;
1453             }
1454             return lcNode;
1455          }
1456
1457       case DELETE:
1458          {
1459             if(!found ||  lcNode == NULLP)
1460             {
1461                DU_LOG("\nERROR  -->  SCH: LCID%d not found; thus Deletion unsuccessful",lcId);
1462             }
1463             else
1464             {
1465                if(deleteNodeFromLList(lcLL, node) == ROK)
1466                   SCH_FREE(lcNode, sizeof(LcInfo));
1467
1468                DU_LOG("\nDEBUG  -->  SCH: LCID%d Deleted successfully",lcId);
1469             }
1470             return NULLP; 
1471          }
1472       case PRINT:
1473       case TRAVERSE_ALL:
1474         {
1475            break;
1476         }
1477       default:
1478          {
1479             DU_LOG("\nERROR  -->  SCH: Action type wrong: %d",action);
1480             break;
1481          }
1482    }
1483    return lcNode;
1484 }
1485
1486 /**************************************************************************
1487  *
1488  * @brief Update ReqPRB for a partiular LCID in LC Linklist 
1489  *
1490  * @details
1491  *
1492  *    Function : updateLcListReqPRB
1493  *
1494  *    Functionality:
1495  *     Update ReqPRB for a partiular LCID in LC Linklist 
1496  *
1497  * @params[in] I/P > lcLinkList pointer (LcInfo list)
1498  *             I/P > lcId
1499  *             I/P > reqPRB
1500  *             I/P > payloadSize
1501  *
1502  * @return ROK/RFAILED
1503  *
1504  * ***********************************************************************/
1505 uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize)
1506 {
1507    LcInfo    *lcNode = NULLP;
1508    lcNode = handleLcLList(lcLL, lcId, CREATE);
1509
1510    if(lcNode == NULLP)
1511    {
1512       DU_LOG("\nERROR  -->  SCH : LC is neither present nor able to create in List lcId:%d",lcId);
1513       return RFAILED;
1514    }
1515
1516    lcNode->reqBO = payloadSize;
1517    lcNode->allocBO = 0;
1518    lcNode->allocPRB = 0; /*Re-Initializing the AllocPRB*/
1519    return ROK;
1520 }
1521
1522 /**************************************************************************
1523  *
1524  * @brief Delete entire LC Linklist 
1525  *
1526  * @details
1527  *
1528  *    Function : deleteLcLL
1529  *
1530  *    Functionality:
1531  *      Delete entire LC Linklist 
1532  *
1533  * @params[in] lcLinkList pointer (LcInfo list)
1534  *
1535  * @return void
1536  *
1537  * ***********************************************************************/
1538 void deleteLcLL(CmLListCp *lcLL)
1539 {
1540    CmLList *node = NULLP, *next = NULLP;
1541    LcInfo *lcNode = NULLP;
1542
1543    if(lcLL == NULLP)
1544    {
1545       DU_LOG("\nERROR  -->  SCH: LcList doesnt exist");
1546       return;
1547    }
1548    node = lcLL->first;
1549
1550    while(node)
1551    {
1552       next = node->next;
1553       lcNode = (LcInfo *)node->node;
1554       if(deleteNodeFromLList(lcLL, node) == ROK)
1555          SCH_FREE(lcNode, sizeof(LcInfo));
1556       node = next;
1557    }
1558 }
1559
1560 /****************************************************************************
1561  *
1562  * @brief Calculate the Estimated TBS Size based on Spec 38.421 , Sec 5.3.1.2
1563  *
1564  * @details
1565  *
1566  *    Function : calculateEstimateTBSize
1567  *
1568  *    Functionality:
1569  *       TBS Size calculation requires numPRB. Since exactPRB for reqBO is unknown thus 
1570  *       will give the PRB value(from 0 to maxRB) one by one and 
1571  *       try to find the TBS size closest to reqBO
1572  *
1573  * @params[in] I/P > reqBO, mcsIdx, num PDSCH symbols, 
1574  *             I/P > maxRB: Maximum PRB count to reach for calculating the TBS
1575  *             O/P > estPrb : Suitable PRB count for reaching the correct TBS
1576  *       
1577  *
1578  * @return TBS Size > Size which will can be allocated for this LC
1579  *        
1580  *
1581  *************************************************************************/
1582 uint32_t calculateEstimateTBSize(uint32_t reqBO, uint16_t mcsIdx, uint8_t numSymbols,\
1583                                    uint16_t maxPRB, uint16_t *estPrb)
1584 {
1585    uint32_t tbs = 0, effecBO = 0;
1586
1587    *estPrb = MIN_PRB;
1588    /*Loop Exit: Either estPRB reaches the maxRB or TBS is found greater than equal to reqBO*/
1589    do
1590    {
1591       tbs = schCalcTbSizeFromNPrb(*estPrb, mcsIdx, numSymbols);
1592
1593       /*TBS size calculated in above function is in Bits. 
1594        * So to convert it into Bytes , we right shift by 3. 
1595        * Eg: tbs=128 bits(1000 0000) ; Right Shift by 3: Tbs = 0001 0000(16 bytes)*/
1596       tbs = tbs >> 3;
1597       *estPrb += 1;
1598    }while((tbs < reqBO) && (*estPrb < maxPRB));
1599
1600    /*Effective BO is the Grant which can be provided for this LC.
1601     * Here,it is decided based on whether we can fully cater its requirment (reqBO) 
1602     * or has to provide lesser grant due to resource limitation.
1603     * Thus effective BO/Grant for this LC will be min of TBS calculated and reqBO*/
1604    effecBO = MIN(tbs,reqBO);
1605    return (effecBO);
1606 }
1607
1608
1609 /*******************************************************************
1610 *
1611 * @brief deleting Page Info node from PageInfo List
1612 *
1613 * @details
1614 *
1615 *    Function : schDeleteFromPageInfoList
1616 *
1617 *    Functionality: deleting page Info node from Page Info List
1618 *
1619 * @params[in] CmLListCp *list, CmLList *node 
1620 *
1621 * @return void 
1622 *
1623 * ****************************************************************/
1624 void schDeleteFromPageInfoList(CmLListCp *list, CmLList *node)
1625 {
1626    SchPageInfo *pageInfo;
1627
1628    if(node != NULLP)
1629    {
1630       pageInfo = (SchPageInfo *)node->node;
1631       if(deleteNodeFromLList(list, node) == ROK)
1632          SCH_FREE(pageInfo, sizeof(SchPageInfo));
1633    }
1634 }
1635
1636 /*******************************************************************
1637 *
1638 * @brief searching for Page at a particular SFN 
1639 *
1640 * @details
1641 *
1642 *    Function : schPageInfoSearchFromPageList
1643 *
1644 *    Functionality: searching for Page at a particular SFN 
1645 *
1646 * @params[in] SlotTimingInfo slotInfo, CmLListCp *storedPageList
1647 *
1648 * @return pointer to SchPageInfo
1649 *
1650 * ****************************************************************/
1651 CmLList *schPageInfoSearchFromPageList(SlotTimingInfo slotInfo, CmLListCp *storedPageList)
1652 {
1653    CmLList         *node = NULLP;
1654    SchPageInfo     *pageInfo = NULLP;
1655
1656    if(storedPageList->count)
1657    {
1658       CM_LLIST_FIRST_NODE(storedPageList, node);
1659       while(node)
1660       {
1661          pageInfo = (SchPageInfo*)node->node;
1662          if(pageInfo == NULLP)
1663          {
1664             DU_LOG("\nERROR  --> SCH: PageInfo empty");
1665          }
1666          else if(pageInfo->pageTxTime.sfn == slotInfo.sfn && 
1667                (pageInfo->pageTxTime.slot == slotInfo.slot))
1668          {
1669             return node;
1670          }
1671          node = node->next;
1672       }
1673    }
1674    return NULLP;
1675 }
1676
1677 /*Below function for printing will be used in future so disabling it for now*/
1678 #if 0
1679 /****************************************************************************
1680  *
1681  * @brief Print the LC in list for debugging purpose 
1682  *
1683  * @details
1684  *
1685  *    Function : printLcLL
1686  *
1687  *    Functionality:
1688  *            For debugging purpose, for printing the LC in the order and
1689  *            parameters
1690  *
1691  * @params[in] LcList pointer 
1692  *       
1693  * @return void 
1694  *        
1695  *************************************************************************/
1696 void printLcLL(CmLListCp *lcLL)
1697 {
1698    CmLList *node = NULLP;
1699    LcInfo *lcNode = NULLP;
1700
1701    if(lcLL == NULLP)
1702    {
1703       DU_LOG("\nINFO   -->  SCH: LcList doesnt exist");
1704       return;
1705    }
1706    node = lcLL->first;
1707    while(node)
1708    {
1709       lcNode = (LcInfo *)node->node;
1710       if(lcNode)
1711       {
1712          DU_LOG("\nINFO   -->  SCH : LcID:%d, [reqBO, allocBO, allocPRB]:[%d,%d,%d]",\
1713                lcNode->lcId,lcNode->reqBO, lcNode->allocBO, lcNode->allocPRB);
1714       }
1715
1716       node = node->next;
1717    }
1718 }
1719 #endif
1720
1721 #ifdef NR_TDD
1722
1723 /**
1724  * @brief determines slot/symbol format
1725  *
1726  * @details
1727  *
1728  *     Function : schGetSlotSymbFrmt 
1729  *      
1730  *      This API is invoked to determine if current slot is DL or UL
1731  *           
1732  *  @param[in]  uint16_t slot
1733  *  @param[in]  uint32_t bitMap from cellCb
1734  *  @return  SlotConfig
1735  *      -# DL    - 0 
1736  *      -# UL    - 1
1737  *      -# FLEXI - 2
1738  **/
1739 SlotConfig schGetSlotSymbFrmt(uint16_t slot, uint32_t bitMap)
1740 {
1741    uint32_t offset = (slot)*2;
1742    return (bitMap & 0x3<<offset)>>offset;
1743 #if 0
1744    SlotConfig slotFrmt;
1745    int mask1 = 0, mask2 = 0;
1746
1747    slot = (slot%n)*2;//n num of slots in defined periodicity or num of symbols
1748    mask1 = 1<<(slot);
1749    mask2 = 1<<(slot+1);
1750    slotFrmt = ((mask1 & bitMap)>>slot) + (2*((mask2 & bitMap)>>(slot+1)));
1751
1752    //printf("\n\n\n\n*****FormatType:%d Slot:%d****\n\n\n\n", slotFrmt, slot/2);
1753
1754    return slotFrmt;
1755 #endif
1756 }
1757
1758 /**
1759  * @brief Determine total length of configured slot pattern for specific 
1760  *    periodicity for TDD
1761  *
1762  * @details
1763  *
1764  *     Function : calculateSlotPatternLength 
1765  *      
1766  *      Determine total length of configured slot pattern for specific periodicity based
1767  *      on slot duration for TDD
1768  *           
1769  *  @param[in]  uint8_t scs, uint8_t periodicity 
1770  *
1771  *  @return uint8_t slotPatternLength 
1772  **/
1773
1774 uint8_t calculateSlotPatternLength(uint8_t scs, uint8_t periodicity)
1775 {
1776    uint8_t slotPatternLength =0;
1777    float   slotDuration = 0;
1778    
1779    /* Calculating the slot duration with the help of SCS.
1780     * This will provides the slot duration in ms like 1, 0.5, 0.25, 0.125. 
1781     * If scs value is SCS_30KHZ its enum value is 1, 
1782     * slotDuration = pow(0.5, 1);
1783     * slotDuration = 0.5 */
1784
1785    slotDuration = pow(0.5,scs);
1786
1787    /* Calculating length of pattern based on Transmission Periodicity. 
1788     * If periodicity = TX_PRDCTY_MS_5,
1789     * slotPatternLength = 5/0.5 
1790     * slotPatternLength = 10 i.e. {length of slot pattern DDDDDDDFUU}*/
1791
1792    switch(periodicity)
1793    {
1794       case TX_PRDCTY_MS_0P5:
1795          slotPatternLength = 0.5/slotDuration;
1796          break;
1797       case TX_PRDCTY_MS_0P625:
1798          slotPatternLength = 0.625/slotDuration;
1799          break;
1800       case TX_PRDCTY_MS_1:
1801          slotPatternLength = 1/slotDuration;
1802          break;
1803       case TX_PRDCTY_MS_1P25:
1804          slotPatternLength = 1.25/slotDuration;
1805          break;
1806       case TX_PRDCTY_MS_2:
1807          slotPatternLength = 2/slotDuration;
1808          break;
1809       case TX_PRDCTY_MS_2P5:
1810          slotPatternLength = 2.5/slotDuration;
1811          break;
1812       case TX_PRDCTY_MS_5:
1813          slotPatternLength = 5/slotDuration;
1814          break;
1815       case TX_PRDCTY_MS_10:
1816          slotPatternLength = 10/slotDuration;
1817          break;
1818    }
1819    return slotPatternLength;
1820 }
1821 #endif
1822
1823 /**
1824  * @brief Function to find start Symbol Index of Coreset defined in SearchSpace(SS)
1825  *
1826  * @details
1827  *
1828  *     Function: findSsStartSymbol
1829  *
1830  *     This function finds first the startSymbol Index of a CORESET 
1831  *     which is defined in SearchSpace.monitoringSymbolWithinSlot parameter
1832  *
1833  *  @param[in]  uint8_t mSymbolsWithinSlot[2]
1834  *        mSymbolsWithinSlot[0] >> MSB as 7th Symbol to LSB as 0th Symbol
1835  *        mSymbolsWithinSlot[1] >> 0th bit as 8th Symbol, 1st bit as 9th,
1836  *                                   ...,5th bit as 13th symbol
1837  *  @return     Success : First SS Symbol Index
1838  *              Failure : MAX_SYMB_PER_SLOT(Invalid value of SymbolIndex = 14)
1839 **/
1840 uint8_t findSsStartSymbol(uint8_t *mSymbolsWithinSlot)
1841 {
1842    uint8_t symbolIdx = 0;
1843    uint8_t i = 1, symPos = 0;
1844
1845    for(symbolIdx = 0; symbolIdx < MONITORING_SYMB_WITHIN_SLOT_SIZE; symbolIdx++)
1846    {
1847       i = 1, symPos = 0;
1848       while(i)
1849       {
1850          /*The first Symbol(or bit) enabled(set) is the StartSymbol of SS thus
1851           *returning if we find that bitPosition */
1852          if(mSymbolsWithinSlot[symbolIdx] & i)
1853          {
1854             /*Adding (SymbolIdx*8) for SymbolIndex between 8 and 13*/
1855             return (symPos + (symbolIdx * 8));
1856          }
1857          i = i << 1;
1858          symPos++;
1859       }
1860    }
1861    return(MAX_SYMB_PER_SLOT);
1862 }
1863
1864 /*
1865  *  @brief: Function will extract the StartPrb as per the given RBGIndex 
1866  *
1867  *  Function: extractStartPrbForRBG
1868  *
1869  *  This function will extract the StartPrb of a rbgIndex. This RbgIndex doesnt
1870  *  have direct mapping with index in FreqDomRsrc instead it is mapping with
1871  *  those rbg which is set(i.e. available for PDCCH)
1872  *
1873  *  @param[in]  uint8_t freqDomainRsrc[6] (As per Spec 38.331, ControlResourceSet.frequencyDomainResources)
1874  *                 freqDomainRsrc[0] =RBG0 to RBG7
1875  *                 freqDomainRsrc[1] =RBG8 to RBG15
1876  *                 ...
1877  *                 freqDomainRsrc[5] =RBG40 to RBG47
1878  *                 (Every RBG has 6 PRBs)
1879  *
1880  *              uint8_t rbgIndex
1881  *
1882  *
1883  *         [return]: startPrb of that rbgIndex
1884  * */
1885 uint16_t extractStartPrbForRBG(uint8_t *freqDomainRsrc, uint8_t rbgIndex)
1886 {
1887    uint8_t freqIdx = 0, idx = 0;
1888    uint8_t count = 0, bitPos = 0;
1889    uint8_t totalPrbPerFreqIdx = NUM_PRBS_PER_RBG * 8; /*8 = no. of Bits in uint8_t*/
1890    uint16_t startPrb = MAX_NUM_RB;
1891
1892    for(freqIdx = 0; freqIdx < FREQ_DOM_RSRC_SIZE; freqIdx++)
1893    {
1894       if(freqDomainRsrc[freqIdx] & 0xFF)
1895       {
1896          /*Tracking from the 7th Bit because in FreqDomRsrc , lowestPRB is
1897           * stored in MSB and so on*/
1898          idx = 128;
1899          bitPos = 0;
1900          while(idx)
1901          {
1902            if(freqDomainRsrc[freqIdx] & idx)
1903            {
1904                if(count == rbgIndex)
1905                {
1906                   startPrb = (totalPrbPerFreqIdx * freqIdx) + (bitPos * NUM_PRBS_PER_RBG);
1907                   return startPrb;
1908                }
1909                count++;
1910            }
1911            bitPos++;
1912            idx = idx >> 1;
1913          }
1914       }
1915    }
1916    return startPrb;
1917 }
1918 /**
1919  * @brief Function to count number of RBG from Coreset's FreqDomainResource 
1920  *
1921  * @details
1922  *
1923  *     Function: countRBGFrmCoresetFreqRsrc
1924  *
1925  * This function counts RBG for calculating the coresetSize using CORESET.freqDomainResource 
1926  * In this, we will find the number of RBG groups which are allowed for this
1927  * coreset
1928  *
1929  *  @param[in]  uint8_t freqDomainRsrc[6] (As per Spec 38.331, ControlResourceSet.frequencyDomainResources)
1930  *              freqDomainRsrc[0] =RBG0 to RBG7
1931  *              freqDomainRsrc[1] =RBG8 to RBG15
1932  *              ...
1933  *              freqDomainRsrc[5] =RBG40 to RBG47
1934  *              (Every RBG has 6 PRBs)
1935  *  @return     Success : Total Number of RGBs in CORESET which can be allocated
1936  *              Failure : 0
1937 **/
1938 uint8_t countRBGFrmCoresetFreqRsrc(uint8_t *freqDomainRsrc)
1939 {
1940    uint8_t freqIdx = 0, idx = 0;
1941    uint8_t count = 0;
1942
1943    for(freqIdx = 0; freqIdx < FREQ_DOM_RSRC_SIZE; freqIdx++)
1944    {
1945       if(freqDomainRsrc[freqIdx] & 0xFF)
1946       {
1947          idx = 1;
1948          while(idx)
1949          {
1950            if(freqDomainRsrc[freqIdx] & idx)
1951            {
1952                count++;
1953            }
1954            idx = idx << 1;
1955          }
1956       }
1957    }
1958    return count;
1959 }
1960
1961 /*
1962  * @brief Function to calculate the DciSize in bits for format 1_0 
1963  *
1964  * @details
1965  *
1966  *   Function: calcUeDciSizeFormat1_0
1967  *   Calculates the totalBit Size for sending this DCI format 1_0 
1968  *   Spec Reference: 38.212, Format 1_0 scrambled using C_RNTI
1969  *
1970  * @Params[in] : CoresetSize (for calculating Frequency domain
1971  *          resource assignment)
1972  **/
1973
1974 uint16_t calcUeDciSizeFormat1_0(uint16_t coresetSize)
1975 {
1976    uint16_t dciSizeInBits = 0;
1977
1978    /* Size(in bits) of each field in DCI format 1_0 */
1979    /*Below fields are identified from 3gpp spec 38.212, 38.213, 38.214*/
1980    uint8_t dciFormatIdSize    = 1;
1981    uint8_t freqDomResAssignSize = 0;
1982    uint8_t timeDomResAssignSize = 4;
1983    uint8_t VRB2PRBMapSize       = 1;
1984    uint8_t modNCodSchemeSize    = 5;
1985    uint8_t ndiSize              = 1;
1986    uint8_t redundancyVerSize    = 2;
1987    uint8_t harqProcessNumSize   = 4;
1988    uint8_t dlAssignmentIdxSize  = 2;
1989    uint8_t pucchTpcSize         = 2;
1990    uint8_t pucchResoIndSize     = 3;
1991    uint8_t harqFeedbackIndSize  = 3;
1992
1993    freqDomResAssignSize = ceil(log2(coresetSize * (coresetSize + 1) / 2));
1994
1995    dciSizeInBits = (dciFormatIdSize + freqDomResAssignSize\
1996          + timeDomResAssignSize + VRB2PRBMapSize + modNCodSchemeSize\
1997          + ndiSize + redundancyVerSize + harqProcessNumSize + dlAssignmentIdxSize\
1998          + pucchTpcSize + pucchResoIndSize + harqFeedbackIndSize);
1999
2000    return(dciSizeInBits);
2001 }
2002
2003 /*
2004  * @brief Function to calculate the aggLvl mapping with CQI index
2005  *
2006  * @details
2007  *
2008  *   Function: fillCqiAggLvlMapping
2009  *
2010  *   Fills the CQI index and Agg level mapping based on 3gpp 38.214,Table 5.2.2.1-2
2011  *   The mapping will be later during PDCCH allocation
2012  *   [Step 1]: Calculate the DciSize in bits. This will be UE-specific as it depends
2013  *             on CORESETsize
2014  *   [Step 2]: Starting from CqiIdx = 0, calculate the efficientPdcchBits which
2015  *   can be sent for that CQI and check if the availBits for each agg level is
2016  *   sufficient for that pdcch required bits.
2017  *        > If the bits required by PDCCH can be contained with Agg Level's
2018  *        availBits then that is assigned.
2019  *  Note:: Good channel, CQI (high value) then Aggrevation level is assigned
2020  *  less(less number of CCE is sufficient) and vice versa for low CQI
2021  *
2022  *  @param[in]: PDCCH Info inside ueCb
2023  *
2024  *       [return]: void
2025  **/
2026
2027 void fillCqiAggLvlMapping(SchPdcchInfo *pdcchInfo)
2028 {
2029    uint8_t cqiIdx = 0, aggLvlIdx =0;
2030    uint16_t numOfBitsAvailForAggLevel = 0, dciSize = 0, pdcchBits = 0;
2031
2032    /*[Step 1]:*/
2033    dciSize = calcUeDciSizeFormat1_0(pdcchInfo->totalPrbs);
2034
2035    /* Initializing the map array*/
2036    memset(pdcchInfo->cqiIndxAggLvlMap, 0, MAX_NUM_CQI_IDX);
2037
2038    /*Note: For CqiIdx = 0, aggLevel is marked as 0 which means that Channel
2039     * Quality is not suitable for any transmission*/
2040    for(cqiIdx = 1; cqiIdx < MAX_NUM_CQI_IDX; cqiIdx++)
2041    {
2042       /*CQI table number 1 is used Spec 38.214 Table 5.2.2.1-2 by default.
2043        *TODO: cqi-table param in CSI-RepotConfig(3gpp 38.331) will report
2044        * which table to be used*/
2045       pdcchBits = ceil(dciSize / cqiTable1[cqiIdx][2]);
2046       for(aggLvlIdx = 0; (aggLvlIdx < MAX_NUM_AGG_LVL) && (pdcchBits != 0); aggLvlIdx++)
2047       {
2048          numOfBitsAvailForAggLevel = (totalRE_PerAggLevel[aggLvlIdx] * cqiTable1[cqiIdx][0]);
2049          /*Check if AggLevel has sufficient bits available for pdcchBits*/
2050          if(pdcchBits < numOfBitsAvailForAggLevel)
2051          {
2052             pdcchInfo->cqiIndxAggLvlMap[cqiIdx] = 1 << aggLvlIdx;
2053             break;
2054          }
2055       }
2056
2057       /*Below case will hit when required pdcchBits is not accomated by any Agg
2058        * Levl which means Channel quality is worse. Thus transmission has to be
2059        * most aggressive thus highest value of Agg level will be used.*/
2060       if(!pdcchInfo->cqiIndxAggLvlMap[cqiIdx])
2061          pdcchInfo->cqiIndxAggLvlMap[cqiIdx] = 16;
2062    }
2063 }
2064
2065 /*
2066  * @brief Function to calculate Value Y 
2067  *
2068  *   Function: schCalY
2069  *
2070  *   Calculates value of YpKp as per [10.1,TS38.213].
2071  *   A0 is for first CS, A1 for second CS and A2 is for third CS
2072  *
2073  *   @params[in]: coresetId and Previous Y
2074  * */
2075 uint32_t schCalY(uint8_t csId, uint32_t prevY)
2076 {
2077    uint32_t A0 = 39827, A1 = 39829, A2 = 39839;
2078    uint32_t D = 65537;
2079
2080    switch(csId % 3)
2081    {
2082       case 0:
2083         {
2084            return((A0 * prevY) % D);                 
2085         } 
2086       case 1:
2087         {
2088            return((A1 * prevY) % D);                 
2089         } 
2090       case 2:
2091         {
2092            return((A2 * prevY) % D);                 
2093         }
2094       default:
2095         {
2096            DU_LOG("\nERROR  --> SCH: Issue in calculating value of Y");
2097            return(0);
2098         }
2099    }
2100    return 0;
2101 }
2102
2103 /*
2104  * @brief Function to calculate the value Y used for CCE Index formula
2105  *
2106  *   Function: schUpdValY
2107  *
2108  *   As per Spec 38.213, Sec 10.1 Formula for CCE Index contains a coefficient
2109  *   value called 'Y' and storing the same in the ueCb which will be later used
2110  *   in pdcch allocation
2111  *
2112  * @params[in] : SchUeCb, PdcchInfo
2113  *    [return] : uint8_t ROK, RFAILED : Memory allocation status
2114  *
2115  * */
2116 uint8_t schUpdValY(SchUeCb *ueCb, SchPdcchInfo *pdcchInfo)
2117 {
2118    uint8_t slotIdx = 0;
2119    if(pdcchInfo->y == NULLP)
2120    {
2121       SCH_ALLOC(pdcchInfo->y, (sizeof(uint32_t) *  ueCb->cellCb->numSlots));
2122       if(pdcchInfo->y == NULLP)
2123       {
2124          DU_LOG("\nERROR  --> SCH: Memory Allocation of Y failed");
2125          return RFAILED;
2126       }
2127    }
2128
2129    for(slotIdx= 0 ; slotIdx < ueCb->cellCb->numSlots; slotIdx++)
2130    {
2131       if(slotIdx == 0)
2132       {
2133          pdcchInfo->y[slotIdx] = schCalY(pdcchInfo->cRSetRef->cRSetId, ueCb->crnti);
2134       }
2135       else
2136       {
2137          pdcchInfo->y[slotIdx] = schCalY(pdcchInfo->cRSetRef->cRSetId, pdcchInfo->y[slotIdx - 1]);
2138       }
2139    }
2140    return ROK;
2141 }
2142
2143 /*
2144  *  @brief : Function to convert SlotPeriodicity to Value
2145  *
2146  *  Function: schConvertSlotPeriodicityEnumToValue
2147  *
2148  *  @param[IN]: SchMSlotPeriodicity enum
2149  *        [return]: slotOffsetVal
2150  * */
2151 uint16_t schConvertSlotPeriodicityEnumToValue(SchMSlotPeriodicity slotPeriod)
2152 {
2153    uint16_t slotPeriodVal = 0;
2154
2155    switch(slotPeriod)
2156    {
2157       case SLOT_PERIODICITY_SL_1:
2158       {
2159          slotPeriodVal = 1;
2160          break;
2161       }
2162       case SLOT_PERIODICITY_SL_2:
2163       {
2164          slotPeriodVal = 2;
2165          break;
2166       }
2167       case SLOT_PERIODICITY_SL_4:
2168       {
2169          slotPeriodVal = 4;
2170          break;
2171       }
2172       case SLOT_PERIODICITY_SL_5:
2173       {
2174          slotPeriodVal = 5;
2175          break;
2176       }
2177       case SLOT_PERIODICITY_SL_8:
2178       {
2179          slotPeriodVal = 8;
2180          break;
2181       }
2182       case SLOT_PERIODICITY_SL_10:
2183       {
2184          slotPeriodVal = 10;
2185          break;
2186       }
2187       case SLOT_PERIODICITY_SL_16:
2188       {
2189          slotPeriodVal = 16;
2190          break;
2191       }
2192       case SLOT_PERIODICITY_SL_20:
2193       {
2194          slotPeriodVal = 20;
2195          break;
2196       }
2197       case SLOT_PERIODICITY_SL_40:
2198       {
2199          slotPeriodVal = 40;
2200          break;
2201       }
2202       case SLOT_PERIODICITY_SL_80:
2203       {
2204          slotPeriodVal = 80;
2205          break;
2206       }
2207       case SLOT_PERIODICITY_SL_160:
2208       {
2209          slotPeriodVal = 160;
2210          break;
2211       }
2212       case SLOT_PERIODICITY_SL_320:
2213       {
2214          slotPeriodVal = 320;
2215          break;
2216       }
2217       case SLOT_PERIODICITY_SL_640:
2218       {
2219          slotPeriodVal = 640;
2220          break;
2221       }
2222       case SLOT_PERIODICITY_SL_1280:
2223       {
2224          slotPeriodVal = 1280;
2225          break;
2226       }
2227       case SLOT_PERIODICITY_SL_2560:
2228       {
2229          slotPeriodVal = 2560;
2230          break;
2231       }
2232       default:
2233       {
2234          slotPeriodVal = 0;
2235          break;
2236       }
2237    }
2238    return slotPeriodVal;
2239 }
2240
2241 /*
2242  *  @brief: Function to extract the numCandidates from aggLevel.
2243  *
2244  *  Function: extractNumOfCandForAggLvl
2245  *
2246  *  @params[IN]: SearchSpace, aggLevel
2247  *         [RETURN]: numCandidates.
2248  * */
2249 uint8_t extractNumOfCandForAggLvl(SchSearchSpace *searchSpace, uint8_t aggLvl)
2250 {
2251    uint8_t numCand = 0;
2252
2253    switch(aggLvl)
2254    {
2255       case 1:
2256       {
2257          numCand = searchSpace->numCandidatesAggLevel1;
2258          break;
2259       }
2260       case 2:
2261       {
2262          numCand = searchSpace->numCandidatesAggLevel2;
2263          break;
2264       }
2265       case 4:
2266       {
2267          numCand = searchSpace->numCandidatesAggLevel4;
2268          break;
2269       }
2270       case 8:
2271       {
2272          numCand = searchSpace->numCandidatesAggLevel8;
2273          break;
2274       }
2275       case 16:
2276       {
2277          numCand = searchSpace->numCandidatesAggLevel16;
2278          break;
2279       }
2280       default:
2281       {
2282          numCand = 0;
2283       }
2284       /*AGGREGATION_LEVEL_N8 enum Value is 7 thus hardcoding the correct Value
2285        * (8)*/
2286       if(numCand == AGGREGATION_LEVEL_N8)
2287       {
2288          numCand = 8;
2289       }
2290    }
2291    return numCand;
2292 }
2293 /**********************************************************************
2294          End of file
2295 **********************************************************************/