5251f71dc69ad609d81a257e4afb2b7840bf9590
[o-du/phy.git] / fhi_lib / lib / src / xran_transport.c
1 /******************************************************************************\r
2 *\r
3 *   Copyright (c) 2019 Intel.\r
4 *\r
5 *   Licensed under the Apache License, Version 2.0 (the "License");\r
6 *   you may not use this file except in compliance with the License.\r
7 *   You may obtain a copy of the License at\r
8 *\r
9 *       http://www.apache.org/licenses/LICENSE-2.0\r
10 *\r
11 *   Unless required by applicable law or agreed to in writing, software\r
12 *   distributed under the License is distributed on an "AS IS" BASIS,\r
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
14 *   See the License for the specific language governing permissions and\r
15 *   limitations under the License.\r
16 *\r
17 *******************************************************************************/\r
18 \r
19 /**\r
20  * @brief This file provides the implementation for Transport lyaer (eCPRI) API.\r
21  *\r
22  * @file xran_transport.c\r
23  * @ingroup group_lte_source_xran\r
24  * @author Intel Corporation\r
25  *\r
26  **/\r
27 \r
28 #include <stdint.h>\r
29 #include <endian.h>\r
30 #include <rte_common.h>\r
31 #include <rte_config.h>\r
32 \r
33 #include "xran_fh_o_du.h"\r
34 #include "xran_common.h"\r
35 #include "xran_transport.h"\r
36 #include "xran_pkt_cp.h"\r
37 #include "xran_cp_api.h"\r
38 #include "xran_up_api.h"\r
39 #include "xran_printf.h"\r
40 \r
41 \r
42 /**\r
43  * @brief return eCPRI header size without eCPRI common header\r
44  *\r
45  * @ingroup xran\r
46  *\r
47  * @return the size of eCPRI header without common header\r
48  */\r
49 int xran_get_ecpri_hdr_size(void)\r
50 {\r
51     return(sizeof(struct xran_ecpri_hdr) - sizeof(struct xran_ecpri_cmn_hdr));\r
52 }\r
53 \r
54 /**\r
55  * @brief Compose ecpriRtcid/ecpriPcid\r
56  *\r
57  * @ingroup xran\r
58  *\r
59  * @param CU_Port_ID CU Port ID\r
60  * @param BanbSector_ID Band Sector ID\r
61  * @param CC_ID Component Carrier ID\r
62  * @param Ant_ID RU Port ID (antenna ID)\r
63  * @return uint16_t composed ecpriRtcid/ecpriPcid (network byte order)\r
64  */\r
65 uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID)\r
66 {\r
67   uint16_t cid;\r
68   struct xran_eaxcid_config *conf;\r
69 \r
70     conf = xran_get_conf_eAxC(NULL);\r
71 \r
72     cid = ((CU_Port_ID      << conf->bit_cuPortId)      & conf->mask_cuPortId)\r
73         | ((BandSector_ID   << conf->bit_bandSectorId)  & conf->mask_bandSectorId)\r
74         | ((CC_ID           << conf->bit_ccId)          & conf->mask_ccId)\r
75         | ((Ant_ID          << conf->bit_ruPortId)      & conf->mask_ruPortId);\r
76 \r
77     return (rte_cpu_to_be_16(cid));\r
78 }\r
79 \r
80 /**\r
81  * @brief Decompose ecpriRtcid/ecpriPcid\r
82  *\r
83  * @ingroup xran\r
84  *\r
85  * @param cid composed ecpriRtcid/ecpriPcid (network byte order)\r
86  * @param result the pointer of the structure to store decomposed values\r
87  * @return none\r
88  */\r
89 void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)\r
90 {\r
91   struct xran_eaxcid_config *conf;\r
92 \r
93     conf = xran_get_conf_eAxC(NULL);\r
94     cid = rte_be_to_cpu_16(cid);\r
95 \r
96     result->cuPortId        = (cid&conf->mask_cuPortId)     >> conf->bit_cuPortId;\r
97     result->bandSectorId    = (cid&conf->mask_bandSectorId) >> conf->bit_bandSectorId;\r
98     result->ccId            = (cid&conf->mask_ccId)         >> conf->bit_ccId;\r
99     result->ruPortId        = (cid&conf->mask_ruPortId)     >> conf->bit_ruPortId;\r
100 \r
101     return;\r
102 }\r
103 \r
104 /**\r
105  * @brief modify the payload size of eCPRI header in xRAN packet\r
106  *\r
107  * @ingroup xran\r
108  *\r
109  * @param mbuf Initialized rte_mbuf packet which has eCPRI header already\r
110  * @param size payload size to be updated\r
111  * @return none\r
112  */\r
113 inline void xran_update_ecpri_payload_size(struct rte_mbuf *mbuf, int size)\r
114 {\r
115   struct xran_ecpri_hdr *ecpri_hdr;\r
116 \r
117     ecpri_hdr = rte_pktmbuf_mtod(mbuf, struct xran_ecpri_hdr *);\r
118 \r
119     ecpri_hdr->cmnhdr.ecpri_payl_size = rte_cpu_to_be_16(size);\r
120 }\r
121 \r
122 \r
123 /**\r
124  * @brief Build ECPRI header and returns added length\r
125  *\r
126  * @ingroup xran\r
127  *\r
128  * @param mbuf\r
129  *  The pointer of the packet buffer to be parsed\r
130  * @param CC_ID\r
131  *  Component Carrier ID for this C-Plane message\r
132  * @param Ant_ID\r
133  *  Antenna ID(RU Port ID) for this C-Plane message\r
134  * @param seq_id\r
135  *  Sequence ID for this C-Plane message\r
136  * @param ecpri_hdr\r
137  *  The pointer to ECPRI header\r
138  * @return\r
139  *  added payload size on success\r
140  *  XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer\r
141  */\r
142 int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,\r
143                         uint8_t CC_ID, uint8_t Ant_ID,\r
144                         uint8_t seq_id,\r
145                         struct xran_ecpri_hdr **ecpri_hdr)\r
146 {\r
147   uint32_t payloadlen;\r
148   struct xran_ecpri_hdr *tmp;\r
149 \r
150 \r
151     tmp = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));\r
152     if(unlikely(tmp == NULL)) {\r
153         print_err("Fail to allocate the space for eCPRI hedaer!");\r
154         return (XRAN_STATUS_RESOURCE);\r
155         }\r
156 \r
157     /* Fill common header */\r
158     tmp->cmnhdr.ecpri_ver           = XRAN_ECPRI_VER;\r
159     tmp->cmnhdr.ecpri_resv          = 0;     // should be zero\r
160     tmp->cmnhdr.ecpri_concat        = 0;\r
161     tmp->cmnhdr.ecpri_mesg_type     = ECPRI_RT_CONTROL_DATA;\r
162     tmp->ecpri_xtc_id               = xran_compose_cid(0, 0, CC_ID, Ant_ID);\r
163 \r
164     /* TODO: Transport layer fragmentation is not supported */\r
165     tmp->ecpri_seq_id.seq_id        = seq_id;\r
166     tmp->ecpri_seq_id.sub_seq_id    = 0;\r
167     tmp->ecpri_seq_id.e_bit         = 1;\r
168 \r
169     /* Starts with eCPRI header size */\r
170     payloadlen = xran_get_ecpri_hdr_size();\r
171 \r
172     *ecpri_hdr = tmp;\r
173 \r
174     return (payloadlen);\r
175 }\r
176 \r
177 /**\r
178  * @brief Parse ECPRI header\r
179  *\r
180  * @ingroup xran\r
181  *\r
182  * @param mbuf\r
183  *  The pointer of the packet buffer to be parsed\r
184  * @param ecpri_hdr\r
185  *  The pointer to ECPRI header\r
186  * @param pkt_info\r
187  *  The pointer of sturcture to store the information from header\r
188  * @return\r
189  *  XRAN_STATUS_SUCCESS on success\r
190  *  XRAN_STATUS_INVALID_PACKET if failed to parse the packet\r
191  */\r
192 int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,\r
193                     struct xran_ecpri_hdr **ecpri_hdr,\r
194                     struct xran_recv_packet_info *pkt_info)\r
195 {\r
196   int ret;\r
197 \r
198 \r
199     *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);\r
200     if(*ecpri_hdr == NULL) {\r
201         print_err("Invalid packet - eCPRI hedaer!");\r
202         return (XRAN_STATUS_INVALID_PACKET);\r
203         }\r
204 \r
205     /* Process eCPRI header */\r
206     ret = XRAN_STATUS_SUCCESS;\r
207     if((*ecpri_hdr)->cmnhdr.ecpri_ver != XRAN_ECPRI_VER) {\r
208         print_err("Invalid eCPRI version - %d", (*ecpri_hdr)->cmnhdr.ecpri_ver);\r
209         ret = XRAN_STATUS_INVALID_PACKET;\r
210         }\r
211     if((*ecpri_hdr)->cmnhdr.ecpri_resv != 0) {\r
212         print_err("Invalid reserved field - %d", (*ecpri_hdr)->cmnhdr.ecpri_resv);\r
213         ret = XRAN_STATUS_INVALID_PACKET;\r
214         }\r
215 \r
216     if(pkt_info != NULL) {\r
217         /* store the information from header */\r
218         pkt_info->ecpri_version = (*ecpri_hdr)->cmnhdr.ecpri_ver;\r
219         pkt_info->msg_type      = (enum ecpri_msg_type)(*ecpri_hdr)->cmnhdr.ecpri_mesg_type;\r
220         pkt_info->payload_len   = rte_be_to_cpu_16((*ecpri_hdr)->cmnhdr.ecpri_payl_size);\r
221 \r
222         pkt_info->seq_id        = (*ecpri_hdr)->ecpri_seq_id.seq_id;\r
223         pkt_info->subseq_id     = (*ecpri_hdr)->ecpri_seq_id.sub_seq_id;\r
224         pkt_info->ebit          = (*ecpri_hdr)->ecpri_seq_id.e_bit;\r
225         xran_decompose_cid((*ecpri_hdr)->ecpri_xtc_id, &(pkt_info->eaxc));\r
226         }\r
227 \r
228     return (ret);\r
229 }\r
230 \r