Adding new commiter to ODU-High repo
[o-du/l2.git] / src / 5gnrmac / lwr_mac_util.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 /* This file contains all utility functions for MAC CL */
20
21 #include "common_def.h"
22 #include "lwr_mac.h"
23
24  /*******************************************************************
25   *
26   * @brief Fetch cellCb from Hash list
27   *
28   * @details
29   *
30   *    Function : rgClUtlGetCellCb
31   *
32   *    Functionality:
33   *       - Searches for a cell entry at MAC CL 
34   *
35   * @params[in] cell Id
36   * @return Pointer to cellCb - success
37   *         NULLP - failure
38   *
39   * ****************************************************************/
40 LwrMacCellCb * lwrMacGetCellCb
41 (
42    uint16_t cellId
43 )
44 {
45    LwrMacCellCb *cellCb;
46
47    if(cellId >= MAX_NUM_CELL)
48    {
49       DU_LOG("\nERROR  -->  Invalid Cell Id [%d]. rgClUtlGetCellCb failed.", cellId);
50       return NULLP;
51    }
52    
53    cellCb = &lwrMacCb.cellCb[cellId -1];
54
55    return cellCb;
56 }
57
58 /*******************************************************************
59  *
60  * @brief Reverses bits in a number
61  *
62  * @details
63  *
64  *    Function : reverseBits
65  *
66  *    Functionality:
67  *      Reverses bits in a number
68  *
69  * @params[in] Number to be reversed
70  *             Number of bits to be reversed
71  * @return Reversed number
72  *
73  * ****************************************************************/
74 uint32_t reverseBits(uint32_t num, uint8_t numBits)
75 {
76    uint32_t reverse_num = 0;
77    uint8_t bitIdx;
78    for (bitIdx = 0; bitIdx < numBits; bitIdx++)
79    {
80       if((num & (1 << bitIdx)))
81          reverse_num |= 1 << ((numBits - 1) - bitIdx);
82    }
83    return reverse_num;
84 }
85
86 /*******************************************************************
87  *
88  * @brief Fills DL DCI payload byte by byte
89  *
90  * @details
91  *
92  *    Function : fillDlDciPayload
93  *
94  *    Functionality:
95  *      Fills DL DCI payload byte by byte
96  *
97  * @params[in] Payload buffer pointer
98  *             Current Byte position in buffer
99  *             Current Bit Position in current byte
100  *             Value to be filled
101  *             Number of bits in value
102  * @return void
103  *
104  * ****************************************************************/
105
106 void fillDlDciPayload(uint8_t *buf, uint8_t *bytePos, uint8_t *bitPos,\
107       uint32_t val, uint8_t valSize)
108 {
109    uint8_t temp;
110    uint8_t bytePart1;
111    uint32_t bytePart2;
112    uint8_t bytePart1Size;
113    uint8_t bytePart2Size;
114
115    if(*bitPos + valSize <= 8)
116    {
117       bytePart1 = (uint8_t)val;
118       bytePart1 = (~((~0) << valSize)) & bytePart1;
119       buf[*bytePos] |= bytePart1;
120       *bitPos += valSize;
121    }
122    else if(*bitPos + valSize > 8)
123    {
124       temp = (uint8_t)val;
125       bytePart1Size = 8 - *bitPos;
126       bytePart2Size = valSize - bytePart1Size;
127
128       bytePart1 = ((~((~0) << bytePart1Size)) & temp) << *bitPos;
129       bytePart2 = val >> bytePart1Size;
130
131       buf[*bytePos] |= bytePart1;
132       (*bytePos)--;
133       *bitPos = 0;
134       fillDlDciPayload(buf, bytePos, bitPos, bytePart2, bytePart2Size);
135    }
136 }
137
138 /*
139  * As per FAPI spec, 
140  * Frequency domain resources is a bitmap defining non-overlapping groups of 6 PRBs in ascending order.
141  * [TS38.213 10.1]. Bitmap of uint8 array. 45 bits.
142  *
143  * As per IAPI,
144  * CORESET-freqdom.frequencyDomainResources : The bits of the bitmap have a one-to-one mapping with
145  * non-overlapping groups of 6 RBs. The most significant bit of the first word corresponds to
146  * the most significant bit defined in 38.331.
147  *
148  * FAPI and IAPI both are 45 bits. Mapped from bit 0 LS Byte for the FAPI and
149  * bit 0 LS U32 entry for IAPI.
150  * FAPI is to be filled in following format such that Intel L1 is able to decode it :
151  *
152  *            FAPI                                 IAPI 
153  * FreqDomainResource[0] bits 7-0     ->    nFreqDomain[0] bits 7-0
154  * FreqDomainResource[1] bits 7-0     ->    nFreqDomain[0] bits 15-8
155  * FreqDomainResource[2] bits 7-0     ->    nFreqDomain[0] bits 23-16
156  * FreqDomainResource[3] bits 7-0     ->    nFreqDomain[0] bits 31-24
157  * FreqDomainResource[4] bits 7-0     ->    nFreqDomain[1] bits 7-0
158  * FreqDomainResource[5] bits 7-0     ->    nFreqDomain[1] bits 15-8
159  *
160  * where for the last entry bits 7,6 and 5 are don't care in the FAPI and bits
161  * 31-13 are don't care in the IAPI.
162  */
163 void convertFreqDomRsrcMapToIAPIFormat(uint8_t *sourceBitMap, uint8_t *destBitMap)
164 {
165    int8_t  idx;
166    uint8_t  numBitsToShift = 0;
167    uint64_t freqDomainResources = 0;
168
169    /* Bit operation to create a 64-bit integer that has
170     * 48 LSBs [Bit 47 to Bit 0] mapped to sourceBitMap[0] to sourceBitMap[5]
171     */
172    for(idx = FREQ_DOM_RSRC_SIZE-1; idx >=0; idx--)
173    {
174       freqDomainResources |= ((uint64_t)sourceBitMap[idx] << numBitsToShift);
175       numBitsToShift += 8;
176    }
177
178    /* Right shift 3 bits because bits[2-0] are unused in sourceBitMap[5] */
179    freqDomainResources = freqDomainResources >> 3;
180
181    /* Filling destBitMap such that LSB bit 0 of freqDomainResources maps to LSB 
182     * of first word of destBitMap */
183    numBitsToShift = 0;
184    for(idx=0; idx<FREQ_DOM_RSRC_SIZE; idx++)
185    {
186       destBitMap[idx] = freqDomainResources >> numBitsToShift;
187       numBitsToShift += 8;
188    }
189 }
190
191 /**********************************************************************
192   End of file
193  **********************************************************************/