--- /dev/null
+/******************************************************************************
+*
+* Copyright (c) 2021 Intel.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*******************************************************************************/
+
+#include "nr5g_fapi_framework.h"
+#include "nr5g_fapi_fapi2phy_p7_pvt_proc.h"
+
+#define FAPI_EMPTY_RB_BITMAP_MASK (0u)
+#define FAPI_EMPTY_RBG_INDEX (0u)
+#define FAPI_MAX_RB_BIT_NUM (273u)
+
+static uint16_t nr5g_fapi_rb_bitmap_mask(
+ uint8_t rbg_size)
+{
+ switch (rbg_size) {
+ case 2:
+ return 0x3u;
+ case 4:
+ return 0xFu;
+ case 8:
+ return 0xFFu;
+ case 16:
+ return 0xFFFFu;
+ default:
+ return FAPI_EMPTY_RB_BITMAP_MASK;
+ }
+}
+
+uint16_t nr5g_fapi_get_rb_bits_for_rbg(
+ const uint8_t rb_bitmap[FAPI_RB_BITMAP_SIZE],
+ uint32_t nth_rbg_bit,
+ uint8_t rbg_size,
+ uint16_t rb_bitmap_mask)
+{
+ uint16_t rb_bits = 0u;
+ const uint16_t rb_bits_bit_size = sizeof(rb_bits) * CHAR_BIT;
+ const uint16_t nth_rb_bit = nth_rbg_bit * rbg_size;
+ const uint32_t rb_byte_1 = ( nth_rb_bit / rb_bits_bit_size ) * sizeof(rb_bits);
+ const uint32_t rb_byte_2 = rb_byte_1 + 1u;
+ if (rb_byte_1 < FAPI_RB_BITMAP_SIZE)
+ {
+ rb_bits |= rb_bitmap[rb_byte_1];
+ }
+ if (rb_byte_2 < FAPI_RB_BITMAP_SIZE)
+ {
+ rb_bits |= (rb_bitmap[rb_byte_2] << CHAR_BIT);
+ }
+ const uint32_t local_rbg_idx = nth_rb_bit % rb_bits_bit_size;
+ return (rb_bits >> local_rbg_idx) & rb_bitmap_mask;
+}
+
+static bool nr5g_fapi_has_rbg_bits_in_rb_bitmap(
+ const uint8_t rb_bitmap[FAPI_RB_BITMAP_SIZE],
+ const uint16_t rbg_bit,
+ const uint8_t rbg_size,
+ const uint16_t rb_bitmap_mask)
+{
+ const uint16_t rb_bits_for_rbg = nr5g_fapi_get_rb_bits_for_rbg(
+ rb_bitmap, rbg_bit, rbg_size, rb_bitmap_mask);
+ if (rb_bitmap_mask == rb_bits_for_rbg)
+ {
+ return true;
+ }
+ else if (FAPI_EMPTY_RB_BITMAP_MASK != rb_bits_for_rbg)
+ {
+ NR5G_FAPI_LOG(ERROR_LOG, ("rb_bits don not match rb_bitmap_mask."
+ " rbg_size %u rbg_bit=%u rb_bits_for_rbg=%#X rb_bitmap_mask=%#X",
+ rbg_size, rbg_bit, rb_bits_for_rbg, rb_bitmap_mask));
+ }
+ return false;
+}
+
+/** @ingroup group_source_api_p7_fapi2phy_proc
+ *
+ * @param[in] rb_bitmap Pointer to FAPI DL resource block bitmap.
+ * @param[in] bwp_start Value of bandwidth partition start.
+ * @param[in] bwp_size Value of bandwidth partition size.
+ * @param[in] rbg_size Value of resource block group size.
+ * @param[in] get_rbg_index_mask Function placing bit in rbgIndex (bit order).
+ *
+ * @return Returns IAPI nRBGIndex
+ *
+ * @description
+ * See TS 138 214 5.1.2.2.1/6.1.2.2.1 for more info.
+ * IAPI uses bit per Resource Block Group,
+ * FAPI uses bit per Virtual Resource Block.
+ * Therefore 1 nRBGIndex bit (IAPI), maps to nRBGSize bits (FAPI)
+ * Bitmaps mappings representation:
+ * IAPI: nRBGIndex = RBG-0................RBG-17 (for PDSCH MSB to LSB,
+ * for PUSCH LSB to MSB)
+ * FAPI RB-0...RB-272:
+ * FAPI rbBitmap[i] = RB-(7+i*8)...........RB-(0+i*8) (MSB to LSB)
+ *
+**/
+uint32_t nr5g_fapi_calc_rbg_index(
+ const uint8_t rb_bitmap[FAPI_RB_BITMAP_SIZE],
+ uint16_t bwp_start,
+ uint16_t bwp_size,
+ uint32_t(*get_rbg_index_mask)(uint32_t nth_bit))
+{
+ const uint8_t rbg_size = nr5g_fapi_calc_n_rbg_size(bwp_size);
+ const uint16_t rb_bitmap_mask = nr5g_fapi_rb_bitmap_mask(rbg_size);
+ if (FAPI_EMPTY_RB_BITMAP_MASK == rb_bitmap_mask)
+ {
+ NR5G_FAPI_LOG(ERROR_LOG, ("Wrong rbg_size=%u. rbg_index set to 0.",
+ rbg_size));
+ return FAPI_EMPTY_RBG_INDEX;
+ }
+ if (bwp_start >= FAPI_MAX_RB_BIT_NUM)
+ {
+ NR5G_FAPI_LOG(ERROR_LOG, ("Wrong bwp_start=%u. rbg_index set to 0.",
+ bwp_start));
+ return FAPI_EMPTY_RBG_INDEX;
+ }
+
+ const uint16_t rbg_bit_begin = bwp_start / rbg_size;
+ const uint16_t rb_bit_end = fmin(FAPI_MAX_RB_BIT_NUM, bwp_start + bwp_size);
+ const uint16_t rbg_bit_last = ceil((double)rb_bit_end / rbg_size) - 1u;
+
+ const uint16_t start_offset = bwp_start % rbg_size;
+ uint16_t rb_bitmap_mask_1st_rbg =
+ rb_bitmap_mask & (rb_bitmap_mask << start_offset);
+ const uint16_t last_rbg_size =
+ (0u == rb_bit_end % rbg_size) ? rbg_size : rb_bit_end % rbg_size;
+ const uint16_t end_offset = rbg_size - last_rbg_size;
+ uint16_t rb_bitmap_mask_last_rbg = rb_bitmap_mask >> end_offset;
+ if (rbg_bit_begin == rbg_bit_last)
+ {
+ const uint16_t mask = rb_bitmap_mask_1st_rbg & rb_bitmap_mask_last_rbg;
+ rb_bitmap_mask_1st_rbg = mask;
+ rb_bitmap_mask_last_rbg = mask;
+ }
+
+ uint32_t result = 0u;
+ // fill 1st rbg
+ if (nr5g_fapi_has_rbg_bits_in_rb_bitmap(
+ rb_bitmap, rbg_bit_begin, rbg_size, rb_bitmap_mask_1st_rbg))
+ {
+ result |= get_rbg_index_mask(rbg_bit_begin);
+ }
+ // fill last rbg
+ if (nr5g_fapi_has_rbg_bits_in_rb_bitmap(
+ rb_bitmap, rbg_bit_last, rbg_size, rb_bitmap_mask_last_rbg))
+ {
+ result |= get_rbg_index_mask(rbg_bit_last);
+ }
+ // fill rest of rbgs
+ uint8_t rbg_bit;
+ for (rbg_bit = rbg_bit_begin + 1u; rbg_bit < rbg_bit_last; rbg_bit++)
+ {
+ if (nr5g_fapi_has_rbg_bits_in_rb_bitmap(
+ rb_bitmap, rbg_bit, rbg_size, rb_bitmap_mask))
+ {
+ result |= get_rbg_index_mask(rbg_bit);
+ }
+ }
+
+ return result;
+}
+
+ /** @ingroup group_source_api_p7_fapi2phy_proc
+ *
+ * @param[in] bwp_size Variable holding the Bandwidth part size.
+ *
+ * @return Returns ::RBG Size.
+ *
+ * @description
+ * This functions calculates and return RBG Size from Bandwidth part size
+ * provided.
+ *
+**/
+uint8_t nr5g_fapi_calc_n_rbg_size(
+ uint16_t bwp_size)
+{
+ uint8_t n_rbg_size = 0;
+ if (bwp_size >= 1 && bwp_size <= 36) {
+ n_rbg_size = 2;
+ } else if (bwp_size >= 37 && bwp_size <= 72) {
+ n_rbg_size = 4;
+ } else if (bwp_size >= 73 && bwp_size <= 144) {
+ n_rbg_size = 8;
+ } else if (bwp_size >= 145 && bwp_size <= 275) {
+ n_rbg_size = 16;
+ } else {
+ n_rbg_size = 0;
+ }
+ return n_rbg_size;
+}
\ No newline at end of file