1 /******************************************************************************
3 * Copyright (c) 2020 Intel.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 *******************************************************************************/
20 * @brief This file provides the implementation for Transport lyaer (eCPRI) API.
22 * @file xran_transport.c
23 * @ingroup group_lte_source_xran
24 * @author Intel Corporation
30 #include <immintrin.h>
31 #include <rte_common.h>
32 #include <rte_config.h>
34 #include "xran_fh_o_du.h"
35 #include "xran_common.h"
36 #include "xran_transport.h"
37 #include "xran_pkt_cp.h"
38 #include "xran_cp_api.h"
39 #include "xran_up_api.h"
40 #include "xran_printf.h"
44 * @brief return eCPRI header size without eCPRI common header
48 * @return the size of eCPRI header without common header
50 int xran_get_ecpri_hdr_size(void)
52 return(sizeof(struct xran_ecpri_hdr) - sizeof(union xran_ecpri_cmn_hdr));
56 * @brief Compose ecpriRtcid/ecpriPcid
60 * @param CU_Port_ID CU Port ID
61 * @param BanbSector_ID Band Sector ID
62 * @param CC_ID Component Carrier ID
63 * @param Ant_ID RU Port ID (antenna ID)
64 * @return uint16_t composed ecpriRtcid/ecpriPcid (network byte order)
66 uint16_t xran_compose_cid(uint8_t CU_Port_ID, uint8_t BandSector_ID, uint8_t CC_ID, uint8_t Ant_ID)
69 struct xran_eaxcid_config *conf;
71 conf = xran_get_conf_eAxC(NULL);
74 rte_panic("conf == NULL");
76 cid = ((CU_Port_ID << conf->bit_cuPortId) & conf->mask_cuPortId)
77 | ((BandSector_ID << conf->bit_bandSectorId) & conf->mask_bandSectorId)
78 | ((CC_ID << conf->bit_ccId) & conf->mask_ccId)
79 | ((Ant_ID << conf->bit_ruPortId) & conf->mask_ruPortId);
81 return (rte_cpu_to_be_16(cid));
85 * @brief Decompose ecpriRtcid/ecpriPcid
89 * @param cid composed ecpriRtcid/ecpriPcid (network byte order)
90 * @param result the pointer of the structure to store decomposed values
93 void xran_decompose_cid(uint16_t cid, struct xran_eaxc_info *result)
95 struct xran_eaxcid_config *conf;
97 conf = xran_get_conf_eAxC(NULL);
98 cid = rte_be_to_cpu_16(cid);
101 rte_panic("conf == NULL");
103 result->cuPortId = (cid&conf->mask_cuPortId) >> conf->bit_cuPortId;
104 result->bandSectorId = (cid&conf->mask_bandSectorId) >> conf->bit_bandSectorId;
105 result->ccId = (cid&conf->mask_ccId) >> conf->bit_ccId;
106 result->ruPortId = (cid&conf->mask_ruPortId) >> conf->bit_ruPortId;
112 * @brief modify the payload size of eCPRI header in xRAN packet
116 * @param mbuf Initialized rte_mbuf packet which has eCPRI header already
117 * @param size payload size to be updated
120 inline void xran_update_ecpri_payload_size(struct rte_mbuf *mbuf, int size)
122 struct xran_ecpri_hdr *ecpri_hdr;
124 ecpri_hdr = rte_pktmbuf_mtod(mbuf, struct xran_ecpri_hdr *);
126 ecpri_hdr->cmnhdr.bits.ecpri_payl_size = rte_cpu_to_be_16(size);
131 * @brief Build ECPRI header and returns added length
136 * The pointer of the packet buffer to be parsed
138 * Component Carrier ID for this C-Plane message
140 * Antenna ID(RU Port ID) for this C-Plane message
142 * Sequence ID for this C-Plane message
144 * The pointer to ECPRI header
146 * added payload size on success
147 * XRAN_STATUS_RESOURCE if failed to allocate the space to packet buffer
149 int xran_build_ecpri_hdr(struct rte_mbuf *mbuf,
150 uint8_t CC_ID, uint8_t Ant_ID,
152 struct xran_ecpri_hdr **ecpri_hdr)
155 struct xran_ecpri_hdr *tmp;
158 tmp = (struct xran_ecpri_hdr *)rte_pktmbuf_append(mbuf, sizeof(struct xran_ecpri_hdr));
159 if(unlikely(tmp == NULL)) {
160 print_err("Fail to allocate the space for eCPRI hedaer!");
161 return (XRAN_STATUS_RESOURCE);
164 /* Fill common header */
165 /*tmp->cmnhdr.bits.ecpri_ver = XRAN_ECPRI_VER;
166 //tmp->cmnhdr.bits.ecpri_resv = 0; // should be zero
167 //tmp->cmnhdr.bits.ecpri_concat = 0;
168 //tmp->cmnhdr.bits.ecpri_mesg_type = ECPRI_RT_CONTROL_DATA;*/
170 tmp->cmnhdr.data.data_num_1 = (XRAN_ECPRI_VER << xran_ecpri_cmn_hdr_bitfield_EcpriVer)
171 | (ECPRI_RT_CONTROL_DATA << xran_ecpri_cmn_hdr_bitfield_EcpriMsgType);
172 tmp->ecpri_xtc_id = xran_compose_cid(0, 0, CC_ID, Ant_ID);
174 /* TODO: Transport layer fragmentation is not supported */
175 //tmp->ecpri_seq_id.bits.seq_id = seq_id;
176 //tmp->ecpri_seq_id.bits.sub_seq_id = 0;
177 //tmp->ecpri_seq_id.bits.e_bit = 1;
178 tmp->ecpri_seq_id.data.data_num_1 = (seq_id << ecpri_seq_id_bitfield_seq_id)
179 | (1 << ecpri_seq_id_bitfield_e_bit);
181 /* Starts with eCPRI header size */
182 payloadlen = XRAN_ECPRI_HDR_SZ; //xran_get_ecpri_hdr_size();
190 * @brief Parse ECPRI header
195 * The pointer of the packet buffer to be parsed
197 * The pointer to ECPRI header
199 * The pointer of sturcture to store the information from header
201 * XRAN_STATUS_SUCCESS on success
202 * XRAN_STATUS_INVALID_PACKET if failed to parse the packet
204 int xran_parse_ecpri_hdr(struct rte_mbuf *mbuf,
205 struct xran_ecpri_hdr **ecpri_hdr,
206 struct xran_recv_packet_info *pkt_info)
208 int ret = XRAN_STATUS_SUCCESS;
210 *ecpri_hdr = rte_pktmbuf_mtod(mbuf, void *);
211 if(*ecpri_hdr == NULL) {
212 print_err("Invalid packet - eCPRI hedaer!");
213 return (XRAN_STATUS_INVALID_PACKET);
216 if(((*ecpri_hdr)->cmnhdr.bits.ecpri_ver != XRAN_ECPRI_VER) || ((*ecpri_hdr)->cmnhdr.bits.ecpri_resv != 0)){
217 print_err("Invalid eCPRI version - %d", (*ecpri_hdr)->cmnhdr.bits.ecpri_ver);
218 print_err("Invalid reserved field - %d", (*ecpri_hdr)->cmnhdr.bits.ecpri_resv);
219 return (XRAN_STATUS_INVALID_PACKET);
222 /* Process eCPRI header */
223 /*if((*ecpri_hdr)->cmnhdr.ecpri_ver != XRAN_ECPRI_VER) {
224 print_err("Invalid eCPRI version - %d", (*ecpri_hdr)->cmnhdr.ecpri_ver);
225 ret = XRAN_STATUS_INVALID_PACKET;
227 /*if((*ecpri_hdr)->cmnhdr.ecpri_resv != 0) {
228 print_err("Invalid reserved field - %d", (*ecpri_hdr)->cmnhdr.ecpri_resv);
229 ret = XRAN_STATUS_INVALID_PACKET;
233 if(pkt_info != NULL) {
234 /* store the information from header */
235 pkt_info->ecpri_version = (*ecpri_hdr)->cmnhdr.bits.ecpri_ver;
236 pkt_info->msg_type = (enum ecpri_msg_type)(*ecpri_hdr)->cmnhdr.bits.ecpri_mesg_type;
237 pkt_info->payload_len = rte_be_to_cpu_16((*ecpri_hdr)->cmnhdr.bits.ecpri_payl_size);
239 pkt_info->seq_id = (*ecpri_hdr)->ecpri_seq_id.bits.seq_id;
240 pkt_info->subseq_id = (*ecpri_hdr)->ecpri_seq_id.bits.sub_seq_id;
241 pkt_info->ebit = (*ecpri_hdr)->ecpri_seq_id.bits.e_bit;
242 xran_decompose_cid((*ecpri_hdr)->ecpri_xtc_id, &(pkt_info->eaxc));