#include "lrg.x" /* layer management typedefs for MAC */
#include "mac_sch_interface.h"
#include "sch.h"
+#include "sch_tmr.h"
#include "sch_utils.h"
#include "math.h"
-/* spec-38.213 Table 13-1 */
+#ifdef NR_TDD
+/* spec-38.213 Table 13-4 for SCS=30KHz */
+/* Note: Picking Table 13-4 and not 13-6 since band supported is n78 and
+ * corresponding minimum B/W is 10 MHz */
+int8_t coresetIdxTable[MAX_CORESET_INDEX][4] = {
+{ 1, 24, 2, 0}, /* index 0 */
+{ 1, 24, 2, 1}, /* index 1 */
+{ 1, 24, 2, 2}, /* index 2 */
+{ 1, 24, 2, 3}, /* index 3 */
+{ 1, 24, 2, 4}, /* index 4 */
+{ 1, 24, 3, 0}, /* index 5 */
+{ 1, 24, 3, 1}, /* index 6 */
+{ 1, 24, 3, 2}, /* index 7 */
+{ 1, 24, 3, 3}, /* index 8 */
+{ 1, 24, 3, 4}, /* index 9 */
+{ 1, 48, 1, 12}, /* index 10 */
+{ 1, 48, 1, 14}, /* index 11 */
+{ 1, 48, 1, 16}, /* index 12 */
+{ 1, 48, 2, 12}, /* index 13 */
+{ 1, 48, 2, 14}, /* index 14 */
+{ 1, 48, 2, 16}, /* index 15 */
+};
+#else
+/* spec-38.213 Table 13-1 for SCS=15KHz */
int8_t coresetIdxTable[MAX_CORESET_INDEX][4] = {
{ 1, 24, 2, 0}, /* index 0 */
{ 1, 24, 2, 2}, /* index 1 */
{ 1, 96, 3, 38}, /* index 14 */
{ 0, 0, 0, 0}, /* index 15 */
};
+#endif
/* spec-38.213 Table 13-11 */
/* m value is scaled to 2, when using it in formula, divide by 2 */
{ 139, 120, 120, 12, 2 }, /* index 15 */
};
+#ifdef NR_TDD
+
+/* prach config index Table 6.3.3.2-3 spec 38.211
+ * PRACH format given as follows:
+ * 0 = 0
+ * 1 = 1
+ * 2 = 2
+ * 3 = 3
+ * 4 = A1
+ * 5 = A2
+ * 6 = A3
+ * 7 = B1
+ * 8 = B4
+ * 9 = C0
+ * 10 = C2
+ * 11 = A1/B1
+ * 12 = A2/B2
+ * 13 = A3/B3
+ * Subframe num is represented considering 0-9 bits and
+ * value 1 corresponds to the subframe that is valid
+ */
+
+uint16_t prachCfgIdxTable[MAX_PRACH_CONFIG_IDX][8] = {
+{ 0, 16, 1, 512, 0, 0, 0, 0 }, /* index 0 */
+{ 0, 8, 1, 512, 0, 0, 0, 0 }, /* index 1 */
+{ 0, 4, 1, 512, 0, 0, 0, 0 }, /* index 2 */
+{ 0, 2, 0, 512, 0, 0, 0, 0 }, /* index 3 */
+{ 0, 2, 1, 512, 0, 0, 0, 0 }, /* index 4 */
+{ 0, 2, 0, 16, 0, 0, 0, 0 }, /* index 5 */
+{ 0, 2, 1, 16, 0, 0, 0, 0 }, /* index 6 */
+{ 0, 1, 0, 512, 0, 0, 0, 0 }, /* index 7 */
+{ 0, 1, 0, 256, 0, 0, 0, 0 }, /* index 8 */
+{ 0, 1, 0, 128, 0, 0, 0, 0 }, /* index 9 */
+{ 0, 1, 0, 64, 0, 0, 0, 0 }, /* index 10 */
+{ 0, 1, 0, 32, 0, 0, 0, 0 }, /* index 11 */
+{ 0, 1, 0, 16, 0, 0, 0, 0 }, /* index 12 */
+{ 0, 1, 0, 8, 0, 0, 0, 0 }, /* index 13 */
+{ 0, 1, 0, 4, 0, 0, 0, 0 }, /* index 14 */
+{ 0, 1, 0, 66, 0, 0, 0, 0 }, /* index 15 */
+{ 0, 1, 0, 66, 7, 0, 0, 0 }, /* index 16 */
+{ 0, 1, 0, 528, 0, 0, 0, 0 }, /* index 17 */
+{ 0, 1, 0, 264, 0, 0, 0, 0 }, /* index 18 */
+{ 0, 1, 0, 132, 0, 0, 0, 0 }, /* index 19 */
+{ 0, 1, 0, 768, 0, 0, 0, 0 }, /* index 20 */
+{ 0, 1, 0, 784, 0, 0, 0, 0 }, /* index 21 */
+{ 0, 1, 0, 536, 0, 0, 0, 0 }, /* index 22 */
+{ 0, 1, 0, 896, 0, 0, 0, 0 }, /* index 23 */
+{ 0, 1, 0, 792, 0, 0, 0, 0 }, /* index 24 */
+{ 0, 1, 0, 960, 0, 0, 0, 0 }, /* index 25 */
+{ 0, 1, 0, 594, 0, 0, 0, 0 }, /* index 26 */
+{ 0, 1, 0, 682, 0, 0, 0, 0 }, /* index 27 */
+{ 1, 16, 1, 128, 0, 0, 0, 0 }, /* index 28 */
+{ 1, 8, 1, 128, 0, 0, 0, 0 }, /* index 29 */
+{ 1, 4, 1, 128, 0, 0, 0, 0 }, /* index 30 */
+{ 1, 2, 0, 128, 0, 0, 0, 0 }, /* index 31 */
+{ 1, 2, 1, 128, 0, 0, 0, 0 }, /* index 32 */
+{ 1, 1, 0, 128, 0, 0, 0, 0 }, /* index 33 */
+{ 2, 16, 1, 64, 0, 0, 0, 0 }, /* index 34 */
+{ 2, 8, 1, 64, 0, 0, 0, 0 }, /* index 35 */
+{ 2, 4, 1, 64, 0, 0, 0, 0 }, /* index 36 */
+{ 2, 2, 0, 64, 7, 0, 0, 0 }, /* index 37 */
+{ 2, 2, 1, 64, 7, 0, 0, 0 }, /* index 38 */
+{ 2, 1, 0, 64, 7, 0, 0, 0 }, /* index 39 */
+{ 3, 16, 1, 512, 0, 0, 0, 0 }, /* index 40 */
+{ 3, 8, 1, 512, 0, 0, 0, 0 }, /* index 41 */
+{ 3, 4, 1, 512, 0, 0, 0, 0 }, /* index 42 */
+{ 3, 2, 0, 512, 0, 0, 0, 0 }, /* index 43 */
+{ 3, 2, 1, 512, 0, 0, 0, 0 }, /* index 44 */
+{ 3, 2, 0, 16, 0, 0, 0, 0 }, /* index 45 */
+{ 3, 2, 1, 16, 0, 0, 0, 0 }, /* index 46 */
+{ 3, 1, 0, 512, 0, 0, 0, 0 }, /* index 47 */
+{ 3, 1, 0, 256, 0, 0, 0, 0 }, /* index 48 */
+{ 3, 1, 0, 128, 0, 0, 0, 0 }, /* index 49 */
+{ 3, 1, 0, 64, 0, 0, 0, 0 }, /* index 50 */
+{ 3, 1, 0, 32, 0, 0, 0, 0 }, /* index 51 */
+{ 3, 1, 0, 16, 0, 0, 0, 0 }, /* index 52 */
+{ 3, 1, 0, 8, 0, 0, 0, 0 }, /* index 53 */
+{ 3, 1, 0, 4, 0, 0, 0, 0 }, /* index 54 */
+{ 3, 1, 0, 66, 0, 0, 0, 0 }, /* index 55 */
+{ 3, 1, 0, 66, 7, 0, 0, 0 }, /* index 56 */
+{ 3, 1, 0, 528, 0, 0, 0, 0 }, /* index 57 */
+{ 3, 1, 0, 264, 0, 0, 0, 0 }, /* index 58 */
+{ 3, 1, 0, 132, 0, 0, 0, 0 }, /* index 59 */
+{ 3, 1, 0, 768, 0, 0, 0, 0 }, /* index 60 */
+{ 3, 1, 0, 784, 0, 0, 0, 0 }, /* index 61 */
+{ 3, 1, 0, 536, 0, 0, 0, 0 }, /* index 62 */
+{ 3, 1, 0, 896, 0, 0, 0, 0 }, /* index 63 */
+{ 3, 1, 0, 792, 0, 0, 0, 0 }, /* index 64 */
+{ 3, 1, 0, 594, 0, 0, 0, 0 }, /* index 65 */
+{ 3, 1, 0, 682, 0, 0, 0, 0 }, /* index 66 */
+{ 4, 16, 1, 512, 0, 2, 6, 2 }, /* index 67 */
+{ 4, 8, 1, 512, 0, 2, 6, 2 }, /* index 68 */
+{ 4, 4, 1, 512, 0, 1, 6, 2 }, /* index 69 */
+{ 4, 2, 1, 512, 0, 1, 6, 2 }, /* index 70 */
+{ 4, 2, 1, 528, 7, 1, 3, 2 }, /* index 71 */
+{ 4, 2, 1, 640, 7, 1, 3, 2 }, /* index 72 */
+{ 4, 2, 1, 640, 0, 1, 6, 2 }, /* index 73 */
+{ 4, 2, 1, 768, 0, 2, 6, 2 }, /* index 74 */
+{ 4, 2, 1, 528, 0, 2, 6, 2 }, /* index 75 */
+{ 4, 2, 1, 924, 0, 1, 6, 2 }, /* index 76 */
+{ 4, 1, 0, 512, 0, 2, 6, 2 }, /* index 77 */
+{ 4, 1, 0, 512, 7, 1, 3, 2 }, /* index 78 */
+{ 4, 1, 0, 512, 0, 1, 6, 2 }, /* index 79 */
+{ 4, 1, 0, 768, 0, 2, 6, 2 }, /* index 80 */
+{ 4, 1, 0, 528, 0, 1, 6, 2 }, /* index 81 */
+{ 4, 1, 0, 640, 7, 1, 3, 2 }, /* index 82 */
+{ 4, 1, 0, 792, 0, 1, 6, 2 }, /* index 83 */
+{ 4, 1, 0, 792, 0, 2, 6, 2 }, /* index 84 */
+{ 4, 1, 0, 682, 0, 1, 6, 2 }, /* index 85 */
+{ 4, 1, 0, 1023, 7, 1, 3, 2 }, /* index 86 */
+{ 5, 16, 1, 512, 0, 2, 3, 4 }, /* index 87 */
+{ 5, 8, 1, 512, 0, 2, 3, 4 }, /* index 88 */
+{ 5, 4, 1, 512, 0, 1, 3, 4 }, /* index 89 */
+{ 5, 2, 1, 640, 0, 1, 3, 4 }, /* index 90 */
+{ 5, 2, 1, 768, 0, 2, 3, 4 }, /* index 91 */
+{ 5, 2, 1, 640, 9, 1, 1, 4 }, /* index 92 */
+{ 5, 2, 1, 528, 9, 1, 1, 4 }, /* index 93 */
+{ 5, 2, 1, 528, 0, 2, 3, 4 }, /* index 94 */
+{ 5, 2, 1, 924, 0, 1, 3, 4 }, /* index 95 */
+{ 5, 1, 0, 4, 0, 1, 3, 4 }, /* index 96 */
+{ 5, 1, 0, 128, 0, 1, 3, 4 }, /* index 97 */
+{ 5, 2, 1, 512, 0, 1, 3, 4 }, /* index 98 */
+{ 5, 1, 0, 512, 0, 2, 3, 4 }, /* index 99 */
+{ 5, 1, 0, 512, 9, 1, 1, 4 }, /* index 100 */
+{ 5, 1, 0, 512, 0, 1, 3, 4 }, /* index 101 */
+{ 5, 1, 0, 132, 0, 1, 3, 4 }, /* index 102 */
+{ 5, 1, 0, 768, 0, 2, 3, 4 }, /* index 103 */
+{ 5, 1, 0, 528, 0, 1, 3, 4 }, /* index 104 */
+{ 5, 1, 0, 640, 9, 1, 1, 4 }, /* index 105 */
+{ 5, 1, 0, 792, 0, 1, 3, 4 }, /* index 106 */
+{ 5, 1, 0, 792, 0, 2, 3, 4 }, /* index 107 */
+{ 5, 1, 0, 682, 0, 1, 3, 4 }, /* index 108 */
+{ 5, 1, 0, 1023, 9, 1, 1, 4 }, /* index 109 */
+{ 6, 16, 1, 512, 0, 2, 2, 6 }, /* index 110 */
+{ 6, 8, 1, 512, 0, 2, 2, 6 }, /* index 111 */
+{ 6, 4, 1, 512, 0, 1, 2, 6 }, /* index 112 */
+{ 6, 2, 1, 528, 7, 1, 1, 6 }, /* index 113 */
+{ 6, 2, 1, 640, 7, 1, 1, 6 }, /* index 114 */
+{ 6, 2, 1, 640, 0, 1, 2, 6 }, /* index 115 */
+{ 6, 2, 1, 528, 0, 2, 2, 6 }, /* index 116 */
+{ 6, 2, 1, 768, 0, 2, 2, 6 }, /* index 117 */
+{ 6, 2, 1, 924, 0, 1, 2, 6 }, /* index 118 */
+{ 6, 1, 0, 4, 0, 1, 2, 6 }, /* index 119 */
+{ 6, 1, 0, 128, 0, 1, 2, 6 }, /* index 120 */
+{ 6, 2, 1, 512, 0, 1, 2, 6 }, /* index 121 */
+{ 6, 1, 0, 512, 0, 2, 2, 6 }, /* index 122 */
+{ 6, 1, 0, 512, 7, 1, 1, 6 }, /* index 123 */
+{ 6, 1, 0, 512, 0, 1, 2, 6 }, /* index 124 */
+{ 6, 1, 0, 132, 0, 1, 2, 6 }, /* index 125 */
+{ 6, 1, 0, 768, 0, 2, 2, 6 }, /* index 126 */
+{ 6, 1, 0, 528, 0, 1, 2, 6 }, /* index 127 */
+{ 6, 1, 0, 640, 7, 1, 1, 6 }, /* index 128 */
+{ 6, 1, 0, 792, 0, 1, 2, 6 }, /* index 129 */
+{ 6, 1, 0, 792, 0, 2, 2, 6 }, /* index 130 */
+{ 6, 1, 0, 682, 0, 1, 2, 6 }, /* index 131 */
+{ 6, 1, 0, 1023, 7, 1, 1, 6 }, /* index 132 */
+{ 7, 4, 1, 512, 2, 1, 6, 2 }, /* index 133 */
+{ 7, 2, 1, 512, 2, 1, 6, 2 }, /* index 134 */
+{ 7, 2, 1, 640, 2, 1, 6, 2 }, /* index 135 */
+{ 7, 2, 1, 528, 8, 1, 3, 2 }, /* index 136 */
+{ 7, 2, 1, 528, 2, 2, 6, 2 }, /* index 137 */
+{ 7, 1, 0, 512, 2, 2, 6, 2 }, /* index 138 */
+{ 7, 1, 0, 512, 8, 1, 3, 2 }, /* index 139 */
+{ 7, 1, 0, 512, 2, 1, 6, 2 }, /* index 140 */
+{ 7, 1, 0, 768, 2, 2, 6, 2 }, /* index 141 */
+{ 7, 1, 0, 528, 2, 1, 6, 2 }, /* index 142 */
+{ 7, 1, 0, 640, 8, 1, 3, 2 }, /* index 143 */
+{ 7, 1, 0, 682, 2, 1, 6, 2 }, /* index 144 */
+{ 8, 16, 1, 512, 0, 2, 1, 12 }, /* index 145 */
+{ 8, 8, 1, 512, 0, 2, 1, 12 }, /* index 146 */
+{ 8, 4, 1, 512, 2, 1, 1, 12 }, /* index 147 */
+{ 8, 2, 1, 512, 0, 1, 1, 12 }, /* index 148 */
+{ 8, 2, 1, 512, 2, 1, 1, 12 }, /* index 149 */
+{ 8, 2, 1, 640, 2, 1, 1, 12 }, /* index 150 */
+{ 8, 2, 1, 528, 2, 1, 1, 12 }, /* index 151 */
+{ 8, 2, 1, 528, 0, 2, 1, 12 }, /* index 152 */
+{ 8, 2, 1, 768, 0, 2, 1, 12 }, /* index 153 */
+{ 8, 2, 1, 924, 0, 1, 1, 12 }, /* index 154 */
+{ 8, 1, 0, 2, 0, 1, 1, 12 }, /* index 155 */
+{ 8, 1, 0, 4, 0, 1, 1, 12 }, /* index 156 */
+{ 8, 1, 0, 16, 0, 1, 1, 12 }, /* index 157 */
+{ 8, 1, 0, 128, 0, 1, 1, 12 }, /* index 158 */
+{ 8, 1, 0, 512, 0, 1, 1, 12 }, /* index 159 */
+{ 8, 1, 0, 512, 2, 1, 1, 12 }, /* index 160 */
+{ 8, 1, 0, 512, 0, 2, 1, 12 }, /* index 161 */
+{ 8, 1, 0, 528, 2, 1, 1, 12 }, /* index 162 */
+{ 8, 1, 0, 640, 2, 1, 1, 12 }, /* index 163 */
+{ 8, 1, 0, 768, 0, 2, 1, 12 }, /* index 164 */
+{ 8, 1, 0, 792, 2, 1, 1, 12 }, /* index 165 */
+{ 8, 1, 0, 682, 2, 1, 1, 12 }, /* index 166 */
+{ 8, 1, 0, 1023, 0, 2, 1, 12 }, /* index 167 */
+{ 8, 1, 0, 1023, 2, 1, 1, 12 }, /* index 168 */
+{ 9, 16, 1, 512, 2, 2, 6, 2 }, /* index 169 */
+{ 9, 8, 1, 512, 2, 2, 6, 2 }, /* index 170 */
+{ 9, 4, 1, 512, 2, 1, 6, 2 }, /* index 171 */
+{ 9, 2, 1, 512, 2, 1, 6, 2 }, /* index 172 */
+{ 9, 2, 1, 768, 2, 2, 6, 2 }, /* index 173 */
+{ 9, 2, 1, 640, 2, 1, 6, 2 }, /* index 174 */
+{ 9, 2, 1, 640, 8, 1, 3, 2 }, /* index 175 */
+{ 9, 2, 1, 528, 8, 1, 3, 2 }, /* index 176 */
+{ 9, 2, 1, 528, 2, 2, 6, 2 }, /* index 177 */
+{ 9, 2, 1, 924, 2, 1, 6, 2 }, /* index 178 */
+{ 9, 1, 0, 512, 2, 2, 6, 2 }, /* index 179 */
+{ 9, 1, 0, 512, 8, 1, 3, 2 }, /* index 180 */
+{ 9, 1, 0, 512, 2, 1, 6, 2 }, /* index 181 */
+{ 9, 1, 0, 768, 2, 2, 6, 2 }, /* index 182 */
+{ 9, 1, 0, 528, 2, 1, 6, 2 }, /* index 183 */
+{ 9, 1, 0, 640, 8, 1, 3, 2 }, /* index 184 */
+{ 9, 1, 0, 792, 2, 1, 6, 2 }, /* index 185 */
+{ 9, 1, 0, 792, 2, 2, 6, 2 }, /* index 186 */
+{ 9, 1, 0, 682, 2, 1, 6, 2 }, /* index 187 */
+{ 9, 1, 0, 1023, 8, 1, 3, 2 }, /* index 188 */
+{10, 16, 1, 512, 2, 2, 2, 6 }, /* index 189 */
+{10, 8, 1, 512, 2, 2, 2, 6 }, /* index 190 */
+{10, 4, 1, 512, 2, 1, 2, 6 }, /* index 191 */
+{10, 2, 1, 512, 2, 1, 2, 6 }, /* index 192 */
+{10, 2, 1, 768, 2, 2, 2, 6 }, /* index 193 */
+{10, 2, 1, 640, 2, 1, 2, 6 }, /* index 194 */
+{10, 2, 1, 640, 8, 1, 1, 6 }, /* index 195 */
+{10, 2, 1, 528, 8, 1, 1, 6 }, /* index 196 */
+{10, 2, 1, 528, 2, 2, 2, 6 }, /* index 197 */
+{10, 2, 1, 924, 2, 1, 2, 6 }, /* index 198 */
+{10, 8, 1, 512, 8, 2, 1, 6 }, /* index 199 */
+{10, 4, 1, 512, 8, 1, 1, 6 }, /* index 200 */
+{10, 1, 0, 512, 2, 2, 2, 6 }, /* index 201 */
+{10, 1, 0, 512, 8, 1, 1, 6 }, /* index 202 */
+{10, 1, 0, 512, 2, 1, 2, 6 }, /* index 203 */
+{10, 1, 0, 768, 2, 2, 2, 6 }, /* index 204 */
+{10, 1, 0, 528, 2, 1, 2, 6 }, /* index 205 */
+{10, 1, 0, 640, 8, 1, 1, 6 }, /* index 206 */
+{10, 1, 0, 792, 2, 1, 2, 6 }, /* index 207 */
+{10, 1, 0, 792, 2, 2, 2, 6 }, /* index 208 */
+{10, 1, 0, 682, 2, 1, 2, 6 }, /* index 209 */
+{10, 1, 0, 1023, 8, 1, 1, 6 }, /* index 210 */
+{11, 2, 1, 512, 2, 1, 6, 2 }, /* index 211 */
+{11, 2, 1, 528, 8, 1, 3, 2 }, /* index 212 */
+{11, 2, 1, 640, 8, 1, 3, 2 }, /* index 213 */
+{11, 2, 1, 640, 2, 1, 6, 2 }, /* index 214 */
+{11, 2, 1, 528, 2, 2, 6, 2 }, /* index 215 */
+{11, 2, 1, 768, 2, 2, 6, 2 }, /* index 216 */
+{11, 1, 0, 512, 2, 2, 6, 2 }, /* index 217 */
+{11, 1, 0, 512, 8, 1, 3, 2 }, /* index 218 */
+{11, 1, 0, 512, 2, 1, 6, 2 }, /* index 219 */
+{11, 1, 0, 768, 2, 2, 6, 2 }, /* index 220 */
+{11, 1, 0, 528, 2, 1, 6, 2 }, /* index 221 */
+{11, 1, 0, 640, 8, 1, 3, 2 }, /* index 222 */
+{11, 1, 0, 792, 2, 2, 6, 2 }, /* index 223 */
+{11, 1, 0, 682, 2, 1, 6, 2 }, /* index 224 */
+{11, 1, 0, 1023, 8, 1, 3, 2 }, /* index 225 */
+{12, 2, 1, 512, 0, 1, 3, 4 }, /* index 226 */
+{12, 2, 1, 528, 6, 1, 2, 4 }, /* index 227 */
+{12, 2, 1, 640, 6, 1, 2, 4 }, /* index 228 */
+{12, 2, 1, 528, 0, 2, 3, 4 }, /* index 229 */
+{12, 2, 1, 768, 0, 2, 3, 4 }, /* index 230 */
+{12, 1, 0, 512, 0, 2, 3, 4 }, /* index 231 */
+{12, 1, 0, 512, 6, 1, 2, 4 }, /* index 232 */
+{12, 1, 0, 512, 0, 1, 3, 4 }, /* index 233 */
+{12, 1, 0, 768, 0, 2, 3, 4 }, /* index 234 */
+{12, 1, 0, 528, 0, 1, 3, 4 }, /* index 235 */
+{12, 1, 0, 640, 6, 1, 2, 4 }, /* index 236 */
+{12, 1, 0, 792, 0, 1, 3, 4 }, /* index 237 */
+{12, 1, 0, 792, 0, 2, 3, 4 }, /* index 238 */
+{12, 1, 0, 682, 0, 1, 3, 4 }, /* index 239 */
+{12, 1, 0, 1023, 6, 1, 2, 4 }, /* index 240 */
+{13, 2, 1, 512, 0, 1, 2, 6 }, /* index 241 */
+{13, 2, 1, 528, 2, 1, 2, 6 }, /* index 242 */
+{13, 2, 1, 640, 0, 1, 2, 6 }, /* index 243 */
+{13, 2, 1, 640, 2, 1, 2, 6 }, /* index 244 */
+{13, 2, 1, 528, 0, 2, 2, 6 }, /* index 245 */
+{13, 2, 1, 768, 0, 2, 2, 6 }, /* index 246 */
+{13, 1, 0, 512, 0, 2, 2, 6 }, /* index 247 */
+{13, 1, 0, 512, 2, 1, 2, 6 }, /* index 248 */
+{13, 1, 0, 512, 0, 1, 2, 6 }, /* index 249 */
+{13, 1, 0, 768, 0, 2, 2, 6 }, /* index 250 */
+{13, 1, 0, 528, 0, 1, 2, 6 }, /* index 251 */
+{13, 1, 0, 640, 2, 1, 2, 6 }, /* index 252 */
+{13, 1, 0, 792, 0, 2, 2, 6 }, /* index 253 */
+{13, 1, 0, 682, 0, 1, 2, 6 }, /* index 254 */
+{13, 1, 0, 1023, 2, 1, 2, 6 } /* index 255 */
+};
+
+#else
/* prach config index Table 6.3.3.2-2 spec 38.211
* PRACH format given as follows:
* 0 = 0
{10, 1, 0, 1023, 0, 2, 2, 6 }, /* index 254 */
{10, 1, 0, 682, 0, 2, 2, 6 } /* index 255 */
};
+#endif
/* Defintion of delta value Table 6.1.2.1.1-5 spec 38.214 */
uint8_t puschDeltaTable[MAX_MU_PUSCH] = { 2, 3, 4, 6 };
{ 31, 6, 0}}; /* mcs index 31 */
/* PUCCH resource sets before dedicated PUCCH resource configuration */
-/* Table 9.2.1-1 spec 38.213 */
-uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][4] = {
-{ 0, 12, 2, 0 }, /* index 0 */
-{ 0, 12, 2, 0 }, /* index 1 */
-{ 0, 12, 2, 3 }, /* index 2 */
-{ 1, 10, 4, 0 }, /* index 3 */
-{ 1, 10, 4, 0 }, /* index 4 */
-{ 1, 10, 4, 2 }, /* index 5 */
-{ 1, 10, 4, 4 }, /* index 6 */
-{ 1, 4, 10, 0 }, /* index 7 */
-{ 1, 4, 10, 0 }, /* index 8 */
-{ 1, 4, 10, 2 }, /* index 9 */
-{ 1, 4, 10, 4 }, /* index 10 */
-{ 1, 0, 14, 0 }, /* index 11 */
-{ 1, 0, 14, 0 }, /* index 12 */
-{ 1, 0, 14, 2 }, /* index 13 */
-{ 1, 0, 14, 4 }, /* index 14 */
-{ 1, 0, 14, 0 }, /* index 15 */
+/* Table 9.2.1-1 spec 38.213 */
+/*{PUCCH_Format, 1stSym, NumSym, PRBOffset, Num_CyclicShift}*/
+uint8_t pucchResourceSet[MAX_PUCCH_RES_SET_IDX][5] = {
+{ 0, 12, 2, 0, 2 }, /* index 0 */
+{ 0, 12, 2, 0, 3 }, /* index 1 */
+{ 0, 12, 2, 3, 3 }, /* index 2 */
+{ 1, 10, 4, 0, 2 }, /* index 3 */
+{ 1, 10, 4, 0, 4 }, /* index 4 */
+{ 1, 10, 4, 2, 4 }, /* index 5 */
+{ 1, 10, 4, 4, 4 }, /* index 6 */
+{ 1, 4, 10, 0, 2 }, /* index 7 */
+{ 1, 4, 10, 0, 4 }, /* index 8 */
+{ 1, 4, 10, 2, 4 }, /* index 9 */
+{ 1, 4, 10, 4, 4 }, /* index 10 */
+{ 1, 0, 14, 0, 2 }, /* index 11 */
+{ 1, 0, 14, 0, 4 }, /* index 12 */
+{ 1, 0, 14, 2, 4 }, /* index 13 */
+{ 1, 0, 14, 4, 4 }, /* index 14 */
+{ 1, 0, 14, (MAX_NUM_RB/4), 4 }, /* index 15 */
+};
+
+/*CQI Table From Spec 38.214 Table 5.2.2.1-2
+ * {Modulation Scheme, CodeRate, Efficiency(bits per symbol)}
+ * Modulation Scheme is numbered based on bit rate as follows
+ * QPSK = 2, 16QAM = 4, 64QAM = 6
+ * */
+float cqiTable1[MAX_NUM_CQI_IDX][3] = {
+{ 0, 0, 0}, /*index 0*/
+{ 2, 78, 0.1523}, /*index 1*/
+{ 2, 120, 0.2344}, /*index 2*/
+{ 2, 193, 0.3770}, /*index 3*/
+{ 2, 308, 0.6016}, /*index 4*/
+{ 2, 449, 0.8770}, /*index 5*/
+{ 2, 602, 1.1758}, /*index 6*/
+{ 4, 378, 1.4766}, /*index 7*/
+{ 4, 490, 1.9141}, /*index 8*/
+{ 4, 616, 2.4063}, /*index 9*/
+{ 6, 466, 2.7305}, /*index 10*/
+{ 6, 567, 3.3223}, /*index 11*/
+{ 6, 666, 3.9023}, /*index 12*/
+{ 6, 772, 4.5234}, /*index 13*/
+{ 6, 873, 5.1152}, /*index 14*/
+{ 6, 948, 5.5547}, /*index 15*/
};
+/*As per Spec 38.211 Table 7.3.2.1-1, using number of CCE per AggLevel
+ * Num of RE for Agg Level = numCCEPerAggLevel * (6 REG) * (12 Subcarriers)
+ */
+uint16_t totalRE_PerAggLevel[MAX_NUM_AGG_LVL]= {72, 144, 288, 576, 1152};
+
+
+/* Minimum Msg3 scheduling time should be calculated based on N1+N2+NTAmax+0.5
+ * ms formula.
+ * Refer spec 38.213 section 8.3.
+ * Harcoding the minimum msg3 scheduling for now */
+uint8_t minMsg3SchTime[MAX_NUM_MU] = {6, 6, 6, 6};
+
+uint8_t defaultUlAckTbl[DEFAULT_UL_ACK_LIST_COUNT]= {1, 2, 3 , 4, 5, 6, 7, 8};
+
+uint8_t schCmnDlRvTbl[4] = {0, 2, 3, 1};
+/**
+ * @brief Function to find first DMRS symbol in PDSCH
+ *
+ * @details
+ *
+ * Function: findDmrsStartSymbol
+ *
+ * This function finds first DMRS symbol using DMRS symbol
+ * position bitmap.
+ *
+ * @param[in] DMRS symbol position bitmap
+ * @return Success : First DRMS symbol
+ * Failure : MAX_SYMB_PER_SLOT
+ **/
+uint8_t findDmrsStartSymbol(uint16_t dlDmrsSymbBitMap)
+{
+ uint8_t position = 0;
+ uint16_t mask = 1;
+
+ while(position < MAX_SYMB_PER_SLOT)
+ {
+ if(dlDmrsSymbBitMap & mask)
+ break;
+ mask = mask << 1;
+ position++;
+ }
+ return position;
+}
+
+/**
+ * @brief Function to add a node to a linked list
+ *
+ * @details
+ *
+ * Function: addNodeToLList
+ *
+ * This function adds a new node to the linked list
+ *
+ * @param[in] Pointer to the list
+ * Pointer to node to be added
+ * Pointer to current node
+ * @return ROK
+ * RFAILED
+ **/
+uint8_t addNodeToLList(CmLListCp *llist, void *blockToAdd, CmLList *currNode)
+{
+ CmLList *newNode;
+
+ SCH_ALLOC(newNode, sizeof(CmLList));
+ if(newNode)
+ {
+ newNode->node = (PTR)blockToAdd;
+
+ if(currNode == NULLP)
+ cmLListAdd2Tail(llist, newNode);
+ else
+ {
+ llist->crnt = currNode;
+ cmLListInsAfterCrnt(llist, newNode);
+ }
+ return ROK;
+ }
+ return RFAILED;
+}
+
+/**
+ * @brief Function to delete a node from linked list
+ *
+ * @details
+ *
+ * Function: deleteNodeFromLList
+ *
+ * This function deletes a node from the linked list
+ *
+ * @param[in] Pointer to the list
+ * Pointer to node to be deleted
+ * @return Pointer to the deleted node
+ **/
+uint8_t deleteNodeFromLList(CmLListCp *llist, CmLList *node)
+{
+ node = cmLListDelFrm(llist, node);
+ SCH_FREE(node, sizeof(CmLList));
+
+ return ROK;
+}
+
+/**
+ * @brief Checks if requested PRBs are free
+ *
+ * @details
+ *
+ * Function: isPrbAvailable
+ *
+ * This functions loops through all free PRB blocks and
+ * checks if request PRB block is available for allocation
+ *
+ * @param[in] List of free PRB blocks
+ * First PRB requested
+ * Total number of PRB requested
+ *
+ * @return Returns Pointer to free block
+ * NULL
+ **/
+CmLList* isPrbAvailable(CmLListCp *freePrbBlockList, uint16_t startPrb, uint16_t numPrb)
+{
+ uint16_t endPrb = 0;
+ CmLList *node = NULLP;
+ FreePrbBlock *freeBlock = NULLP;
+
+ endPrb = startPrb + numPrb - 1;
+
+ /* Iterate through all blocks of free PRB to check if requested PRBs can be assigned */
+ node = freePrbBlockList->first;
+ while(node)
+ {
+ freeBlock = (FreePrbBlock *)node->node;
+
+ /* Check if requested number of blocks can be allocated from the current block */
+ if(freeBlock->numFreePrb < numPrb)
+ {
+ DU_LOG("\nINFO --> SCH: In isPrbAvailable, numFreePrb:%d is less than reqPrb:%d", freeBlock->numFreePrb, numPrb);
+ node = node->next;
+ continue;
+ }
+
+ /* Check if requested PRBs belong within the range of current free block */
+ if(((startPrb >= freeBlock->startPrb) && (startPrb <= freeBlock->endPrb)) && \
+ ((endPrb >= freeBlock->startPrb) && (endPrb <= freeBlock->endPrb)))
+ {
+ return node;
+ }
+
+ /* If current block is unable to provide resources, check the next block */
+ node = node->next;
+ }
+ return NULLP;
+}
+
+/**
+ * @brief Function to update free PRB list
+ *
+ * @details
+ *
+ * Function: removeAllocatedPrbFromFreePrbList
+ *
+ * This function removes the allocated PRBs from the
+ * list of free PRBs
+ *
+ * @param[in] Pointer to the list
+ * Pointer to node from which PRB was allocated
+ * Start PRB allocated
+ * Number of PRBs allocated
+ * @return void
+ **/
+void removeAllocatedPrbFromFreePrbList(CmLListCp *freePrbBlockList, CmLList *node, uint16_t startPrb, uint16_t numPrb)
+{
+ uint16_t endPrb;
+ FreePrbBlock *newBlock = NULLP;
+ FreePrbBlock *freeBlock = (FreePrbBlock *)node->node;
+
+ if(!node)
+ return;
+
+ endPrb = startPrb + numPrb -1;
+
+ /* If the whole block is allocated, remove it from linked list */
+ if(freeBlock->numFreePrb == numPrb)
+ {
+ if(deleteNodeFromLList(freePrbBlockList, node) == ROK)
+ SCH_FREE(freeBlock, sizeof(FreePrbBlock));
+ }
+
+ /* If PRB is allocated from start of free block, move the start of free block
+ * after last alloctaed PRB */
+ else if(freeBlock->startPrb == startPrb)
+ {
+ freeBlock->startPrb = endPrb+1;
+ freeBlock->numFreePrb = freeBlock->endPrb - freeBlock->startPrb +1;
+ }
+
+ /* If PRB is allocated from end of free block, move the end of free block
+ * before the first allocated PRB */
+ else if(freeBlock->endPrb == endPrb)
+ {
+ freeBlock->endPrb = startPrb-1;
+ freeBlock->numFreePrb = freeBlock->endPrb - freeBlock->startPrb +1;
+ }
+
+ /* If PRBs are allocated somewhere in between the free block, split it into 2
+ * nodes. Fist node contains free PRBs after the allocated PRBs. Second node
+ * contains free PRBs present before the allocated PRBs */
+ else
+ {
+ /* Block 2 */
+ SCH_ALLOC(newBlock, sizeof(FreePrbBlock));
+ if(newBlock)
+ {
+ newBlock->startPrb = freeBlock->startPrb;
+ newBlock->endPrb = startPrb-1;
+ newBlock->numFreePrb = newBlock->endPrb - newBlock->startPrb +1;
+ addNodeToLList(freePrbBlockList, newBlock, node);
+ }
+
+ /* Block 1 */
+ freeBlock->startPrb = endPrb+1;
+ freeBlock->numFreePrb = freeBlock->endPrb - freeBlock->startPrb +1;
+ }
+}
+
/**
* @brief frequency domain allocation function.
*
* @param[in] payLoadSize - size of payload in bytes
* @return TBsize from the Table in bytes
**/
-uint16_t schCalcTbSize(uint16_t payLoadSize)
+uint16_t schCalcTbSize(uint32_t payLoadSize)
{
uint8_t tbsIndex = 0;
- payLoadSize = payLoadSize*8;
+ uint16_t maxTbSize;
+
+ maxTbSize = tbSizeTable[TOTAL_TBSIZE_VALUES -1]/8;
+ if(payLoadSize >= maxTbSize)
+ return maxTbSize;
+ payLoadSize = payLoadSize*8;
while(payLoadSize > tbSizeTable[tbsIndex])
{
tbsIndex++;
uint8_t qm = mcsTable[mcs][1];
uint16_t rValue = mcsTable[mcs][2];
uint8_t numLayer = 1; /* v value */
+ uint8_t numDmrsRePerPrb = 12;
tbSize = tbSize * 8; //Calculate tbSize in bits
- /* formula used for calculation of rbSize, 38.213 section 5.1.3.2 *
- * Ninfo = Nre . R . Qm . v *
+ /* formula used for calculation of rbSize, 38.214 section 5.1.3.2 *
+ * Ninfo = S . Nre . R . Qm . v *
* Nre' = Nsc . NsymPdsch - NdmrsSymb - Noh *
* Nre = min(156,Nre') . nPrb */
nre = ceil( (float)tbSize * 1024 / (qm * rValue * numLayer));
- nreDash = ceil( (12 * numSymbols) - NUM_DMRS_SYMBOLS - 0);
+ nreDash = ceil( (12 * numSymbols) - numDmrsRePerPrb - 0);
if (nreDash > 156)
- nre = 156;
+ nreDash = 156;
numPrb = ceil((float)nre / nreDash);
return numPrb;
}
+/**
+* @brief calculation of transport block size.
+*
+* @details
+*
+* Function: schCalcTbSizeFromNPrb
+*
+* This function calculates the transport block size
+*
+* @param[in] nPrb is num PRB
+* @param[in] mcs
+* @param[in] number of symbols
+* @return tbSize
+**/
+uint16_t schCalcTbSizeFromNPrb(uint16_t numPrb, uint16_t mcs, uint8_t numSymbols)
+{
+ uint8_t qm = mcsTable[mcs][1];
+ uint16_t rValue = mcsTable[mcs][2];
+ uint16_t tbsIndex = 0;
+ uint32_t tbSize = 0;
+ uint32_t nre = 0;
+ uint32_t nreDash = 0;
+ uint32_t nInfo = 0;
+ uint32_t n = 0;
+ uint32_t nInfoDash = 0;
+ uint32_t c = 0;
+ const uint8_t numLayer = 1;
+ const uint16_t numRbSc = 12;
+ const uint16_t numDmrsRes = 12;
+ const uint16_t sf = 1;
+// uint16_t numPrbOvrHead = 0;
+
+ /* formula used for calculation of rbSize, 38.214 section 5.1.3.2 *
+ * Ninfo = Nre . R . Qm . v where [ NInfo is tbSize] *
+ * Nre' = Nsc . NsymPdsch - NdmrsSymb - Noh *
+ * Nre = min(156,Nre') . nPrb */
+
+ nreDash = MIN(156, ceil( (numRbSc * numSymbols) - numDmrsRes - 0));
+ nre = nreDash * numPrb;
+ nInfo = ceil(nre * qm * numLayer * rValue/(1024.0 * sf));
+
+ if(nInfo <= 3824)
+ {
+ n = MAX(3, (uint32_t)cmLog2(nInfo) - 6);
+ nInfoDash = MAX(24, (1<<n)*(nInfo/(1<<n)));
+ while(nInfoDash > tbSizeTable[tbsIndex])
+ {
+ tbsIndex++;
+ }
+ tbSize = tbSizeTable[tbsIndex];
+ }
+ else
+ {
+ n = (uint32_t)cmLog2(nInfo - 24) - 5;
+ nInfoDash = MAX(3840, (1<<n)*ceil((nInfo - 24)/(1<<n)));
+
+ if(rValue<256)
+ {
+ c = ceil((nInfoDash + 24)/3816);
+ tbSize = 8 * c * ceil((nInfoDash + 24)/(8 * c)) - 24;
+ }
+ else
+ {
+ if(nInfoDash > 8424)
+ {
+ c = ceil((nInfoDash + 24)/8424);
+ tbSize = 8 * c * ceil((nInfoDash + 24)/(8 * c)) - 24;
+ }
+ else
+ {
+ tbSize = 8 * ceil((nInfoDash + 24)/(8)) - 24;
+ }
+ }
+ }
+ return tbSize;
+}
+
/**
* @brief fetching ueCb from cellCb
*
**/
SchUeCb* schGetUeCb(SchCellCb *cellCb, uint16_t crnti)
{
- uint16_t ueIdx;
- GET_UE_IDX(crnti, ueIdx);
- return &(cellCb->ueCb[ueIdx -1]);
+ uint16_t ueId;
+ GET_UE_ID(crnti, ueId);
+ return &(cellCb->ueCb[ueId -1]);
}
/**
**/
void schInitUlSlot(SchUlSlotInfo *schUlSlotInfo)
{
- memset(schUlSlotInfo, 0, sizeof(SchUlSlotInfo));
- schUlSlotInfo->totalPrb = MAX_NUM_RB;
- for(uint8_t itr=0; itr<SCH_SYMBOL_PER_SLOT; itr++)
+ uint8_t ueIdx = 0;
+ CmLList *node = NULLP, *next = NULLP;
+ FreePrbBlock *freeBlock;
+
+ /* Delete the old blocks */
+ if(schUlSlotInfo->prbAlloc.freePrbBlockList.count)
+ {
+ node = schUlSlotInfo->prbAlloc.freePrbBlockList.first;
+ }
+ while(node)
{
- schUlSlotInfo->assignedPrb[itr] = 0;
+ next = node->next;
+ freeBlock = (FreePrbBlock *)node->node;
+ if(deleteNodeFromLList(&schUlSlotInfo->prbAlloc.freePrbBlockList, node) == ROK)
+ SCH_FREE(freeBlock, sizeof(FreePrbBlock));
+ node = next;
}
- schUlSlotInfo->puschCurrentPrb = PUSCH_START_RB;
- schUlSlotInfo->schPuschInfo = NULLP;
+ /* Initilize UL Slot info and mark all PRBs as free */
+ memset(schUlSlotInfo, 0, sizeof(SchUlSlotInfo));
+ cmLListInit(&schUlSlotInfo->prbAlloc.freePrbBlockList);
+ SCH_ALLOC(freeBlock, sizeof(FreePrbBlock));
+ if(freeBlock)
+ {
+ freeBlock->numFreePrb = MAX_NUM_RB;
+ freeBlock->startPrb = 0;
+ freeBlock->endPrb = MAX_NUM_RB-1;
+ addNodeToLList(&schUlSlotInfo->prbAlloc.freePrbBlockList, freeBlock, NULL);
+ }
+
+ for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+ {
+ schUlSlotInfo->schPuschInfo[ueIdx] = NULLP;
+ }
}
/**
**/
void schInitDlSlot(SchDlSlotInfo *schDlSlotInfo)
{
+ CmLList *node = NULLP, *next = NULLP;
+ FreePrbBlock *freeBlock;
+
+ /* Delete the old blocks */
+ if(schDlSlotInfo->prbAlloc.freePrbBlockList.count)
+ node = schDlSlotInfo->prbAlloc.freePrbBlockList.first;
+ while(node)
+ {
+ next = node->next;
+ freeBlock = (FreePrbBlock *)node->node;
+ if(deleteNodeFromLList(&schDlSlotInfo->prbAlloc.freePrbBlockList, node) == ROK)
+ SCH_FREE(freeBlock, sizeof(FreePrbBlock));
+ node = next;
+ }
+
+ /* Initilize DL Slot info and mark all PRBs as free */
memset(schDlSlotInfo, 0, sizeof(SchDlSlotInfo));
- schDlSlotInfo->totalPrb = MAX_NUM_RB;
- for(uint8_t itr=0; itr<SCH_SYMBOL_PER_SLOT; itr++)
+ cmLListInit(&schDlSlotInfo->prbAlloc.freePrbBlockList);
+ SCH_ALLOC(freeBlock, sizeof(FreePrbBlock));
+ if(freeBlock)
{
- schDlSlotInfo->assignedPrb[itr] = 0;
+ freeBlock->numFreePrb = MAX_NUM_RB;
+ freeBlock->startPrb = 0;
+ freeBlock->endPrb = MAX_NUM_RB-1;
+ addNodeToLList(&schDlSlotInfo->prbAlloc.freePrbBlockList, freeBlock, NULL);
}
-
- for(uint8_t itr=0; itr<MAX_SSB_IDX; itr++)
+}
+
+/**
+ * @brief Fill resource bit map
+ *
+ * @details
+ *
+ * Function: fillPrbBitmap
+ *
+ * This function updates bitMap to mark the allocated PRBs
+ *
+ * @param[in] schDlSlotInfo
+ * @return void
+ **/
+bool fillPrbBitmap(uint64_t *prbBitMap, uint16_t startPrb, uint16_t numPrb)
+{
+ uint16_t bitMapIdx = 0;
+ uint16_t offsetInFirstIdx = 0;
+ uint32_t numBitsToSetInFirstIdx = 0;
+ uint64_t mask = MASK_BIT64_ON;
+ uint64_t bitmapBackup[PRB_BITMAP_MAX_IDX];
+
+ /* Store backup of the bitmap in order to roll back if PRB allocation fails */
+ memcpy(bitmapBackup, prbBitMap, sizeof(bitmapBackup));
+
+ /* Calculate the bitmap idx and offset of bit in that idx, to start
+ * allocating PRBs from */
+ bitMapIdx = startPrb / PRB_BITMAP_IDX_LEN;
+ offsetInFirstIdx = startPrb % PRB_BITMAP_IDX_LEN;
+
+ /* If number of PRBs allocated >= number of unset bits in first idx starting from offset bit
+ * then set all bits in first idx starting from offset bit
+ * else set bits equal to number of PRBs allocated
+ */
+ numBitsToSetInFirstIdx = \
+ (numPrb >= (PRB_BITMAP_IDX_LEN-offsetInFirstIdx)) ? (PRB_BITMAP_IDX_LEN-offsetInFirstIdx) : numPrb;
+
+ mask = mask >> (PRB_BITMAP_IDX_LEN-numBitsToSetInFirstIdx);
+ mask = mask<<offsetInFirstIdx;
+
+ /* If PRBs to be allocated are not already in use, mark these PRBs as allocated */
+ if(!(prbBitMap[bitMapIdx] & mask))
{
- memset(&schDlSlotInfo->ssbInfo[itr], 0, sizeof(SsbInfo));
+ prbBitMap[bitMapIdx] = prbBitMap[bitMapIdx] | mask;
+
+ bitMapIdx++;
+ numPrb = numPrb - numBitsToSetInFirstIdx;
+ /* Set all bits in a bitMapIdx until remaining numPrb is less than PRB_BITMAP_IDX_LEN */
+ while(numPrb > PRB_BITMAP_IDX_LEN)
+ {
+ if(prbBitMap[bitMapIdx])
+ {
+ memcpy(prbBitMap, bitmapBackup, sizeof(bitmapBackup));
+ return RFAILED;
+ }
+ prbBitMap[bitMapIdx] = MASK_BIT64_ON;
+ bitMapIdx++;
+ numPrb = numPrb - PRB_BITMAP_IDX_LEN;
+ }
+
+ /* Set bits for the remaining PRBs */
+ if(numPrb)
+ {
+ mask = MASK_BIT64_ON;
+ mask = mask >> (PRB_BITMAP_IDX_LEN-numPrb);
+ if(!(prbBitMap[bitMapIdx] & mask))
+ {
+ prbBitMap[bitMapIdx] = prbBitMap[bitMapIdx] | mask;
+ }
+ else
+ {
+ memcpy(prbBitMap, bitmapBackup, sizeof(bitmapBackup));
+ return RFAILED;
+ }
+ }
}
+ else
+ {
+ return RFAILED;
+ }
+
+ return ROK;
+}
+/**************************************************************************
+ *
+ * @brief Update the LCID Node in LCLL as per ActionType
+ *
+ * @details
+ *
+ * Function : handleLcLList
+ *
+ * Functionality:
+ * Search LCID in LCLL or if not found, create,Delete, or return
+ * node for this LCID
+ *
+ * @params[in] I/P > lcLinkList pointer (LcInfo list)
+ * I/P > lcId
+ * I/P > ActionType (Create,Delete or Just search)
+ *
+ * @return lcNode > Pointer to the Node for that LcInfo
+ * If NULLP, FATAL FAILURE
+ *
+ * ***********************************************************************/
+LcInfo* handleLcLList(CmLListCp *lcLL, uint8_t lcId, ActionTypeLL action)
+{
+ CmLList *node = NULLP;
+ LcInfo *lcNode = NULLP;
+ bool found = FALSE;
+
+ if(lcLL == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: LcList doesnt exist");
+ return NULLP;
+ }
+ node = lcLL->first;
+
+ /*Traversing the LC LinkList*/
+ while(node)
+ {
+ lcNode = (LcInfo *)node->node;
+ if(lcNode->lcId == lcId)
+ {
+ found = TRUE;
+ break;
+ }
+ node = node->next;
+ }//end of while
+
+ switch(action)
+ {
+ case SEARCH:
+ {
+ if(!found)
+ {
+ lcNode = NULLP;
+ }
+ return lcNode;
+ }
+
+ case CREATE:
+ {
+ if(node != NULLP)
+ return lcNode;
+
+ /*Need to add a new node for this LC*/
+
+ /*List is empty; Initialize the LL ControlPointer*/
+ if(lcLL->count == 0)
+ {
+ cmLListInit(lcLL);
+ }
+
+ lcNode = NULLP;
+ /*Allocate the List*/
+ SCH_ALLOC(lcNode, sizeof(LcInfo));
+ if(lcNode)
+ {
+ lcNode->lcId = lcId;
+ lcNode->reqBO = 0;
+ lcNode->allocBO = 0;
+ lcNode->allocPRB = 0;
+ }
+ else
+ {
+ DU_LOG("\nERROR --> SCH : Allocation of List failed,lcId:%d",lcId);
+ return NULLP;
+ }
+
+ if(addNodeToLList(lcLL, lcNode, NULLP) == RFAILED)
+ {
+ DU_LOG("\nERROR --> SCH : failed to Add Node,lcId:%d",lcId);
+ SCH_FREE(lcNode, sizeof(LcInfo));
+ return NULLP;
+ }
+ return lcNode;
+ }
+
+ case DELETE:
+ {
+ if(!found || lcNode == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: LCID%d not found; thus Deletion unsuccessful",lcId);
+ }
+ else
+ {
+ if(deleteNodeFromLList(lcLL, node) == ROK)
+ SCH_FREE(lcNode, sizeof(LcInfo));
+
+ DU_LOG("\nDEBUG --> SCH: LCID%d Deleted successfully",lcId);
+ }
+ return NULLP;
+ }
+ case PRINT:
+ case TRAVERSE_ALL:
+ {
+ break;
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> SCH: Action type wrong: %d",action);
+ break;
+ }
+ }
+ return lcNode;
+}
+
+/**************************************************************************
+ *
+ * @brief Update ReqPRB for a partiular LCID in LC Linklist
+ *
+ * @details
+ *
+ * Function : updateLcListReqPRB
+ *
+ * Functionality:
+ * Update ReqPRB for a partiular LCID in LC Linklist
+ *
+ * @params[in] I/P > lcLinkList pointer (LcInfo list)
+ * I/P > lcId
+ * I/P > reqPRB
+ * I/P > payloadSize
+ *
+ * @return ROK/RFAILED
+ *
+ * ***********************************************************************/
+uint8_t updateLcListReqPRB(CmLListCp *lcLL, uint8_t lcId, uint32_t payloadSize)
+{
+ LcInfo *lcNode = NULLP;
+ lcNode = handleLcLList(lcLL, lcId, CREATE);
+
+ if(lcNode == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH : LC is neither present nor able to create in List lcId:%d",lcId);
+ return RFAILED;
+ }
+
+ lcNode->reqBO = payloadSize;
+ lcNode->allocBO = 0;
+ lcNode->allocPRB = 0; /*Re-Initializing the AllocPRB*/
+ return ROK;
+}
+
+/**************************************************************************
+ *
+ * @brief Delete entire LC Linklist
+ *
+ * @details
+ *
+ * Function : deleteLcLL
+ *
+ * Functionality:
+ * Delete entire LC Linklist
+ *
+ * @params[in] lcLinkList pointer (LcInfo list)
+ *
+ * @return void
+ *
+ * ***********************************************************************/
+void deleteLcLL(CmLListCp *lcLL)
+{
+ CmLList *node = NULLP, *next = NULLP;
+ LcInfo *lcNode = NULLP;
+
+ if(lcLL == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: LcList doesnt exist");
+ return;
+ }
+ node = lcLL->first;
+
+ while(node)
+ {
+ next = node->next;
+ lcNode = (LcInfo *)node->node;
+ if(deleteNodeFromLList(lcLL, node) == ROK)
+ SCH_FREE(lcNode, sizeof(LcInfo));
+ node = next;
+ }
+}
+
+/****************************************************************************
+ *
+ * @brief Calculate the Estimated TBS Size based on Spec 38.421 , Sec 5.3.1.2
+ *
+ * @details
+ *
+ * Function : calculateEstimateTBSize
+ *
+ * Functionality:
+ * TBS Size calculation requires numPRB. Since exactPRB for reqBO is unknown thus
+ * will give the PRB value(from 0 to maxRB) one by one and
+ * try to find the TBS size closest to reqBO
+ *
+ * @params[in] I/P > reqBO, mcsIdx, num PDSCH symbols,
+ * I/P > maxRB: Maximum PRB count to reach for calculating the TBS
+ * O/P > estPrb : Suitable PRB count for reaching the correct TBS
+ *
+ *
+ * @return TBS Size > Size which will can be allocated for this LC
+ *
+ *
+ *************************************************************************/
+uint32_t calculateEstimateTBSize(uint32_t reqBO, uint16_t mcsIdx, uint8_t numSymbols,\
+ uint16_t maxPRB, uint16_t *estPrb)
+{
+ uint32_t tbs = 0, effecBO = 0;
+
+ *estPrb = MIN_PRB;
+ /*Loop Exit: Either estPRB reaches the maxRB or TBS is found greater than equal to reqBO*/
+ do
+ {
+ tbs = schCalcTbSizeFromNPrb(*estPrb, mcsIdx, numSymbols);
+
+ /*TBS size calculated in above function is in Bits.
+ * So to convert it into Bytes , we right shift by 3.
+ * Eg: tbs=128 bits(1000 0000) ; Right Shift by 3: Tbs = 0001 0000(16 bytes)*/
+ tbs = tbs >> 3;
+ *estPrb += 1;
+ }while((tbs < reqBO) && (*estPrb < maxPRB));
+
+ /*Effective BO is the Grant which can be provided for this LC.
+ * Here,it is decided based on whether we can fully cater its requirment (reqBO)
+ * or has to provide lesser grant due to resource limitation.
+ * Thus effective BO/Grant for this LC will be min of TBS calculated and reqBO*/
+ effecBO = MIN(tbs,reqBO);
+ return (effecBO);
+}
+
+
+/*******************************************************************
+*
+* @brief deleting Page Info node from PageInfo List
+*
+* @details
+*
+* Function : schDeleteFromPageInfoList
+*
+* Functionality: deleting page Info node from Page Info List
+*
+* @params[in] CmLListCp *list, CmLList *node
+*
+* @return void
+*
+* ****************************************************************/
+void schDeleteFromPageInfoList(CmLListCp *list, CmLList *node)
+{
+ SchPageInfo *pageInfo;
+
+ if(node != NULLP)
+ {
+ pageInfo = (SchPageInfo *)node->node;
+ if(deleteNodeFromLList(list, node) == ROK)
+ SCH_FREE(pageInfo, sizeof(SchPageInfo));
+ }
+}
+
+/*******************************************************************
+*
+* @brief searching for Page at a particular SFN
+*
+* @details
+*
+* Function : schPageInfoSearchFromPageList
+*
+* Functionality: searching for Page at a particular SFN
+*
+* @params[in] SlotTimingInfo slotInfo, CmLListCp *storedPageList
+*
+* @return pointer to SchPageInfo
+*
+* ****************************************************************/
+CmLList *schPageInfoSearchFromPageList(SlotTimingInfo slotInfo, CmLListCp *storedPageList)
+{
+ CmLList *node = NULLP;
+ SchPageInfo *pageInfo = NULLP;
+
+ if(storedPageList->count)
+ {
+ CM_LLIST_FIRST_NODE(storedPageList, node);
+ while(node)
+ {
+ pageInfo = (SchPageInfo*)node->node;
+ if(pageInfo == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: PageInfo empty");
+ }
+ else if(pageInfo->pageTxTime.sfn == slotInfo.sfn &&
+ (pageInfo->pageTxTime.slot == slotInfo.slot))
+ {
+ return node;
+ }
+ node = node->next;
+ }
+ }
+ return NULLP;
+}
+
+/*Below function for printing will be used in future so disabling it for now*/
+#if 0
+/****************************************************************************
+ *
+ * @brief Print the LC in list for debugging purpose
+ *
+ * @details
+ *
+ * Function : printLcLL
+ *
+ * Functionality:
+ * For debugging purpose, for printing the LC in the order and
+ * parameters
+ *
+ * @params[in] LcList pointer
+ *
+ * @return void
+ *
+ *************************************************************************/
+void printLcLL(CmLListCp *lcLL)
+{
+ CmLList *node = NULLP;
+ LcInfo *lcNode = NULLP;
+
+ if(lcLL == NULLP)
+ {
+ DU_LOG("\nINFO --> SCH: LcList doesnt exist");
+ return;
+ }
+ node = lcLL->first;
+ while(node)
+ {
+ lcNode = (LcInfo *)node->node;
+ if(lcNode)
+ {
+ DU_LOG("\nINFO --> SCH : LcID:%d, [reqBO, allocBO, allocPRB]:[%d,%d,%d]",\
+ lcNode->lcId,lcNode->reqBO, lcNode->allocBO, lcNode->allocPRB);
+ }
+
+ node = node->next;
+ }
+}
+#endif
+
+#ifdef NR_TDD
+
+/**
+ * @brief determines slot/symbol format
+ *
+ * @details
+ *
+ * Function : schGetSlotSymbFrmt
+ *
+ * This API is invoked to determine if current slot is DL or UL
+ *
+ * @param[in] uint16_t slot
+ * @param[in] uint32_t bitMap from cellCb
+ * @return SlotConfig
+ * -# DL - 0
+ * -# UL - 1
+ * -# FLEXI - 2
+ **/
+SlotConfig schGetSlotSymbFrmt(uint16_t slot, uint32_t bitMap)
+{
+ uint32_t offset = (slot)*2;
+ return (bitMap & 0x3<<offset)>>offset;
+#if 0
+ SlotConfig slotFrmt;
+ int mask1 = 0, mask2 = 0;
+
+ slot = (slot%n)*2;//n num of slots in defined periodicity or num of symbols
+ mask1 = 1<<(slot);
+ mask2 = 1<<(slot+1);
+ slotFrmt = ((mask1 & bitMap)>>slot) + (2*((mask2 & bitMap)>>(slot+1)));
+
+ //printf("\n\n\n\n*****FormatType:%d Slot:%d****\n\n\n\n", slotFrmt, slot/2);
+
+ return slotFrmt;
+#endif
+}
+
+/**
+ * @brief Determine total length of configured slot pattern for specific
+ * periodicity for TDD
+ *
+ * @details
+ *
+ * Function : calculateSlotPatternLength
+ *
+ * Determine total length of configured slot pattern for specific periodicity based
+ * on slot duration for TDD
+ *
+ * @param[in] uint8_t scs, uint8_t periodicity
+ *
+ * @return uint8_t slotPatternLength
+ **/
+
+uint8_t calculateSlotPatternLength(uint8_t scs, uint8_t periodicity)
+{
+ uint8_t slotPatternLength =0;
+ float slotDuration = 0;
+
+ /* Calculating the slot duration with the help of SCS.
+ * This will provides the slot duration in ms like 1, 0.5, 0.25, 0.125.
+ * If scs value is SCS_30KHZ its enum value is 1,
+ * slotDuration = pow(0.5, 1);
+ * slotDuration = 0.5 */
+
+ slotDuration = pow(0.5,scs);
+
+ /* Calculating length of pattern based on Transmission Periodicity.
+ * If periodicity = TX_PRDCTY_MS_5,
+ * slotPatternLength = 5/0.5
+ * slotPatternLength = 10 i.e. {length of slot pattern DDDDDDDFUU}*/
+
+ switch(periodicity)
+ {
+ case TX_PRDCTY_MS_0P5:
+ slotPatternLength = 0.5/slotDuration;
+ break;
+ case TX_PRDCTY_MS_0P625:
+ slotPatternLength = 0.625/slotDuration;
+ break;
+ case TX_PRDCTY_MS_1:
+ slotPatternLength = 1/slotDuration;
+ break;
+ case TX_PRDCTY_MS_1P25:
+ slotPatternLength = 1.25/slotDuration;
+ break;
+ case TX_PRDCTY_MS_2:
+ slotPatternLength = 2/slotDuration;
+ break;
+ case TX_PRDCTY_MS_2P5:
+ slotPatternLength = 2.5/slotDuration;
+ break;
+ case TX_PRDCTY_MS_5:
+ slotPatternLength = 5/slotDuration;
+ break;
+ case TX_PRDCTY_MS_10:
+ slotPatternLength = 10/slotDuration;
+ break;
+ }
+ return slotPatternLength;
+}
+#endif
+
+/**
+ * @brief Function to find start Symbol Index of Coreset defined in SearchSpace(SS)
+ *
+ * @details
+ *
+ * Function: findSsStartSymbol
+ *
+ * This function finds first the startSymbol Index of a CORESET
+ * which is defined in SearchSpace.monitoringSymbolWithinSlot parameter
+ *
+ * @param[in] uint8_t mSymbolsWithinSlot[2]
+ * mSymbolsWithinSlot[0] >> MSB as 7th Symbol to LSB as 0th Symbol
+ * mSymbolsWithinSlot[1] >> 0th bit as 8th Symbol, 1st bit as 9th,
+ * ...,5th bit as 13th symbol
+ * @return Success : First SS Symbol Index
+ * Failure : MAX_SYMB_PER_SLOT(Invalid value of SymbolIndex = 14)
+**/
+uint8_t findSsStartSymbol(uint8_t *mSymbolsWithinSlot)
+{
+ uint8_t symbolIdx = 0;
+ uint8_t i = 1, symPos = 0;
+
+ for(symbolIdx = 0; symbolIdx < MONITORING_SYMB_WITHIN_SLOT_SIZE; symbolIdx++)
+ {
+ i = 1, symPos = 0;
+ while(i)
+ {
+ /*The first Symbol(or bit) enabled(set) is the StartSymbol of SS thus
+ *returning if we find that bitPosition */
+ if(mSymbolsWithinSlot[symbolIdx] & i)
+ {
+ /*Adding (SymbolIdx*8) for SymbolIndex between 8 and 13*/
+ return (symPos + (symbolIdx * 8));
+ }
+ i = i << 1;
+ symPos++;
+ }
+ }
+ return(MAX_SYMB_PER_SLOT);
+}
+
+/*
+ * @brief: Function will extract the StartPrb as per the given RBGIndex
+ *
+ * Function: extractStartPrbForRBG
+ *
+ * This function will extract the StartPrb of a rbgIndex. This RbgIndex doesnt
+ * have direct mapping with index in FreqDomRsrc instead it is mapping with
+ * those rbg which is set(i.e. available for PDCCH)
+ *
+ * @param[in] uint8_t freqDomainRsrc[6] (As per Spec 38.331, ControlResourceSet.frequencyDomainResources)
+ * freqDomainRsrc[0] =RBG0 to RBG7
+ * freqDomainRsrc[1] =RBG8 to RBG15
+ * ...
+ * freqDomainRsrc[5] =RBG40 to RBG47
+ * (Every RBG has 6 PRBs)
+ *
+ * uint8_t rbgIndex
+ *
+ *
+ * [return]: startPrb of that rbgIndex
+ * */
+uint16_t extractStartPrbForRBG(uint8_t *freqDomainRsrc, uint8_t rbgIndex)
+{
+ uint8_t freqIdx = 0, idx = 0;
+ uint8_t count = 0, bitPos = 0;
+ uint8_t totalPrbPerFreqIdx = NUM_PRBS_PER_RBG * 8; /*8 = no. of Bits in uint8_t*/
+ uint16_t startPrb = MAX_NUM_RB;
+
+ for(freqIdx = 0; freqIdx < FREQ_DOM_RSRC_SIZE; freqIdx++)
+ {
+ if(freqDomainRsrc[freqIdx] & 0xFF)
+ {
+ /*Tracking from the 7th Bit because in FreqDomRsrc , lowestPRB is
+ * stored in MSB and so on*/
+ idx = 128;
+ bitPos = 0;
+ while(idx)
+ {
+ if(freqDomainRsrc[freqIdx] & idx)
+ {
+ if(count == rbgIndex)
+ {
+ startPrb = (totalPrbPerFreqIdx * freqIdx) + (bitPos * NUM_PRBS_PER_RBG);
+ return startPrb;
+ }
+ count++;
+ }
+ bitPos++;
+ idx = idx >> 1;
+ }
+ }
+ }
+ return startPrb;
+}
+/**
+ * @brief Function to count number of RBG from Coreset's FreqDomainResource
+ *
+ * @details
+ *
+ * Function: countRBGFrmCoresetFreqRsrc
+ *
+ * This function counts RBG for calculating the coresetSize using CORESET.freqDomainResource
+ * In this, we will find the number of RBG groups which are allowed for this
+ * coreset
+ *
+ * @param[in] uint8_t freqDomainRsrc[6] (As per Spec 38.331, ControlResourceSet.frequencyDomainResources)
+ * freqDomainRsrc[0] =RBG0 to RBG7
+ * freqDomainRsrc[1] =RBG8 to RBG15
+ * ...
+ * freqDomainRsrc[5] =RBG40 to RBG47
+ * (Every RBG has 6 PRBs)
+ * @return Success : Total Number of RGBs in CORESET which can be allocated
+ * Failure : 0
+**/
+uint8_t countRBGFrmCoresetFreqRsrc(uint8_t *freqDomainRsrc)
+{
+ uint8_t freqIdx = 0, idx = 0;
+ uint8_t count = 0;
+
+ for(freqIdx = 0; freqIdx < FREQ_DOM_RSRC_SIZE; freqIdx++)
+ {
+ if(freqDomainRsrc[freqIdx] & 0xFF)
+ {
+ idx = 1;
+ while(idx)
+ {
+ if(freqDomainRsrc[freqIdx] & idx)
+ {
+ count++;
+ }
+ idx = idx << 1;
+ }
+ }
+ }
+ return count;
+}
+
+/*
+ * @brief Function to calculate the DciSize in bits for format 1_0
+ *
+ * @details
+ *
+ * Function: calcUeDciSizeFormat1_0
+ * Calculates the totalBit Size for sending this DCI format 1_0
+ * Spec Reference: 38.212, Format 1_0 scrambled using C_RNTI
+ *
+ * @Params[in] : CoresetSize (for calculating Frequency domain
+ * resource assignment)
+ **/
+
+uint16_t calcUeDciSizeFormat1_0(uint16_t coresetSize)
+{
+ uint16_t dciSizeInBits = 0;
+
+ /* Size(in bits) of each field in DCI format 1_0 */
+ /*Below fields are identified from 3gpp spec 38.212, 38.213, 38.214*/
+ uint8_t dciFormatIdSize = 1;
+ uint8_t freqDomResAssignSize = 0;
+ uint8_t timeDomResAssignSize = 4;
+ uint8_t VRB2PRBMapSize = 1;
+ uint8_t modNCodSchemeSize = 5;
+ uint8_t ndiSize = 1;
+ uint8_t redundancyVerSize = 2;
+ uint8_t harqProcessNumSize = 4;
+ uint8_t dlAssignmentIdxSize = 2;
+ uint8_t pucchTpcSize = 2;
+ uint8_t pucchResoIndSize = 3;
+ uint8_t harqFeedbackIndSize = 3;
+
+ freqDomResAssignSize = ceil(log2(coresetSize * (coresetSize + 1) / 2));
+
+ dciSizeInBits = (dciFormatIdSize + freqDomResAssignSize\
+ + timeDomResAssignSize + VRB2PRBMapSize + modNCodSchemeSize\
+ + ndiSize + redundancyVerSize + harqProcessNumSize + dlAssignmentIdxSize\
+ + pucchTpcSize + pucchResoIndSize + harqFeedbackIndSize);
+
+ return(dciSizeInBits);
+}
+
+/*
+ * @brief Function to calculate the aggLvl mapping with CQI index
+ *
+ * @details
+ *
+ * Function: fillCqiAggLvlMapping
+ *
+ * Fills the CQI index and Agg level mapping based on 3gpp 38.214,Table 5.2.2.1-2
+ * The mapping will be later during PDCCH allocation
+ * [Step 1]: Calculate the DciSize in bits. This will be UE-specific as it depends
+ * on CORESETsize
+ * [Step 2]: Starting from CqiIdx = 0, calculate the efficientPdcchBits which
+ * can be sent for that CQI and check if the availBits for each agg level is
+ * sufficient for that pdcch required bits.
+ * > If the bits required by PDCCH can be contained with Agg Level's
+ * availBits then that is assigned.
+ * Note:: Good channel, CQI (high value) then Aggrevation level is assigned
+ * less(less number of CCE is sufficient) and vice versa for low CQI
+ *
+ * @param[in]: PDCCH Info inside ueCb
+ *
+ * [return]: void
+ **/
+
+void fillCqiAggLvlMapping(SchPdcchInfo *pdcchInfo)
+{
+ uint8_t cqiIdx = 0, aggLvlIdx =0;
+ uint16_t numOfBitsAvailForAggLevel = 0, dciSize = 0, pdcchBits = 0;
+
+ /*[Step 1]:*/
+ dciSize = calcUeDciSizeFormat1_0(pdcchInfo->totalPrbs);
+
+ /* Initializing the map array*/
+ memset(pdcchInfo->cqiIndxAggLvlMap, 0, MAX_NUM_CQI_IDX);
+
+ /*Note: For CqiIdx = 0, aggLevel is marked as 0 which means that Channel
+ * Quality is not suitable for any transmission*/
+ for(cqiIdx = 1; cqiIdx < MAX_NUM_CQI_IDX; cqiIdx++)
+ {
+ /*CQI table number 1 is used Spec 38.214 Table 5.2.2.1-2 by default.
+ *TODO: cqi-table param in CSI-RepotConfig(3gpp 38.331) will report
+ * which table to be used*/
+ pdcchBits = ceil(dciSize / cqiTable1[cqiIdx][2]);
+ for(aggLvlIdx = 0; (aggLvlIdx < MAX_NUM_AGG_LVL) && (pdcchBits != 0); aggLvlIdx++)
+ {
+ numOfBitsAvailForAggLevel = (totalRE_PerAggLevel[aggLvlIdx] * cqiTable1[cqiIdx][0]);
+ /*Check if AggLevel has sufficient bits available for pdcchBits*/
+ if(pdcchBits < numOfBitsAvailForAggLevel)
+ {
+ pdcchInfo->cqiIndxAggLvlMap[cqiIdx] = 1 << aggLvlIdx;
+ break;
+ }
+ }
+
+ /*Below case will hit when required pdcchBits is not accomated by any Agg
+ * Levl which means Channel quality is worse. Thus transmission has to be
+ * most aggressive thus highest value of Agg level will be used.*/
+ if(!pdcchInfo->cqiIndxAggLvlMap[cqiIdx])
+ pdcchInfo->cqiIndxAggLvlMap[cqiIdx] = 16;
+ }
+}
+
+/*
+ * @brief Function to calculate Value Y
+ *
+ * Function: schCalY
+ *
+ * Calculates value of YpKp as per [10.1,TS38.213].
+ * A0 is for first CS, A1 for second CS and A2 is for third CS
+ *
+ * @params[in]: coresetId and Previous Y
+ * */
+uint32_t schCalY(uint8_t csId, uint32_t prevY)
+{
+ uint32_t A0 = 39827, A1 = 39829, A2 = 39839;
+ uint32_t D = 65537;
+
+ switch(csId % 3)
+ {
+ case 0:
+ {
+ return((A0 * prevY) % D);
+ }
+ case 1:
+ {
+ return((A1 * prevY) % D);
+ }
+ case 2:
+ {
+ return((A2 * prevY) % D);
+ }
+ default:
+ {
+ DU_LOG("\nERROR --> SCH: Issue in calculating value of Y");
+ return(0);
+ }
+ }
+ return 0;
+}
+
+/*
+ * @brief Function to calculate the value Y used for CCE Index formula
+ *
+ * Function: schUpdValY
+ *
+ * As per Spec 38.213, Sec 10.1 Formula for CCE Index contains a coefficient
+ * value called 'Y' and storing the same in the ueCb which will be later used
+ * in pdcch allocation
+ *
+ * @params[in] : SchUeCb, PdcchInfo
+ * [return] : uint8_t ROK, RFAILED : Memory allocation status
+ *
+ * */
+uint8_t schUpdValY(SchUeCb *ueCb, SchPdcchInfo *pdcchInfo)
+{
+ uint8_t slotIdx = 0;
+ if(pdcchInfo->y == NULLP)
+ {
+ SCH_ALLOC(pdcchInfo->y, (sizeof(uint32_t) * ueCb->cellCb->numSlots));
+ if(pdcchInfo->y == NULLP)
+ {
+ DU_LOG("\nERROR --> SCH: Memory Allocation of Y failed");
+ return RFAILED;
+ }
+ }
+
+ for(slotIdx= 0 ; slotIdx < ueCb->cellCb->numSlots; slotIdx++)
+ {
+ if(slotIdx == 0)
+ {
+ pdcchInfo->y[slotIdx] = schCalY(pdcchInfo->cRSetRef->cRSetId, ueCb->crnti);
+ }
+ else
+ {
+ pdcchInfo->y[slotIdx] = schCalY(pdcchInfo->cRSetRef->cRSetId, pdcchInfo->y[slotIdx - 1]);
+ }
+ }
+ return ROK;
+}
+
+/*
+ * @brief : Function to convert SlotPeriodicity to Value
+ *
+ * Function: schConvertSlotPeriodicityEnumToValue
+ *
+ * @param[IN]: SchMSlotPeriodicity enum
+ * [return]: slotOffsetVal
+ * */
+uint16_t schConvertSlotPeriodicityEnumToValue(SchMSlotPeriodicity slotPeriod)
+{
+ uint16_t slotPeriodVal = 0;
+
+ switch(slotPeriod)
+ {
+ case SLOT_PERIODICITY_SL_1:
+ {
+ slotPeriodVal = 1;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_2:
+ {
+ slotPeriodVal = 2;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_4:
+ {
+ slotPeriodVal = 4;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_5:
+ {
+ slotPeriodVal = 5;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_8:
+ {
+ slotPeriodVal = 8;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_10:
+ {
+ slotPeriodVal = 10;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_16:
+ {
+ slotPeriodVal = 16;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_20:
+ {
+ slotPeriodVal = 20;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_40:
+ {
+ slotPeriodVal = 40;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_80:
+ {
+ slotPeriodVal = 80;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_160:
+ {
+ slotPeriodVal = 160;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_320:
+ {
+ slotPeriodVal = 320;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_640:
+ {
+ slotPeriodVal = 640;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_1280:
+ {
+ slotPeriodVal = 1280;
+ break;
+ }
+ case SLOT_PERIODICITY_SL_2560:
+ {
+ slotPeriodVal = 2560;
+ break;
+ }
+ default:
+ {
+ slotPeriodVal = 0;
+ break;
+ }
+ }
+ return slotPeriodVal;
+}
+
+/*
+ * @brief: Function to extract the numCandidates from aggLevel.
+ *
+ * Function: extractNumOfCandForAggLvl
+ *
+ * @params[IN]: SearchSpace, aggLevel
+ * [RETURN]: numCandidates.
+ * */
+uint8_t extractNumOfCandForAggLvl(SchSearchSpace *searchSpace, uint8_t aggLvl)
+{
+ uint8_t numCand = 0;
+
+ switch(aggLvl)
+ {
+ case 1:
+ {
+ numCand = searchSpace->numCandidatesAggLevel1;
+ break;
+ }
+ case 2:
+ {
+ numCand = searchSpace->numCandidatesAggLevel2;
+ break;
+ }
+ case 4:
+ {
+ numCand = searchSpace->numCandidatesAggLevel4;
+ break;
+ }
+ case 8:
+ {
+ numCand = searchSpace->numCandidatesAggLevel8;
+ break;
+ }
+ case 16:
+ {
+ numCand = searchSpace->numCandidatesAggLevel16;
+ break;
+ }
+ default:
+ {
+ numCand = 0;
+ }
+ /*AGGREGATION_LEVEL_N8 enum Value is 7 thus hardcoding the correct Value
+ * (8)*/
+ if(numCand == AGGREGATION_LEVEL_N8)
+ {
+ numCand = 8;
+ }
+ }
+ return numCand;
}
/**********************************************************************
End of file