/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 * * 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. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ /*! \file openair1/PHY/CODING * \brief: load library implementing coding/decoding algorithms * \author Francois TABURET * \date 2017 * \version 0.1 * \company NOKIA BellLabs France * \email: francois.taburet@nokia-bell-labs.com * \note * \warning */ #define _GNU_SOURCE #include <sys/types.h> #include "PHY/defs_common.h" #include "PHY/phy_extern.h" #include "PHY/CODING/coding_extern.h" #include "common/utils/load_module_shlib.h" #include "common/utils/telnetsrv/telnetsrv.h" static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); static telnetshell_cmddef_t coding_cmdarray[] = { {"mode","[sse,avx2,stdc,none]",coding_setmod_cmd}, {"","",NULL}, }; telnetshell_vardef_t coding_vardef[] = { {"maxiter",TELNET_VARTYPE_INT32,&max_turbo_iterations}, {"",0,NULL} }; /* PHY/defs.h contains MODE_DECODE_XXX macros, following table must match */ static char *modedesc[] = {"none","sse","C","avx2"}; static int curmode; /* function description array, to be used when loading the encoding/decoding shared lib */ loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR]; /* encoding decoding functions pointers, filled here and used when encoding/decoding */ /*defined as extern in PHY?CODING/extern.h */ decoder_if_t *decoder16; decoder_if_t *decoder8; encoder_if_t *encoder; extern int _may_i_use_cpu_feature(unsigned __int64); uint8_t nodecod(int16_t *y, int16_t *y2, uint8_t *decoded_bytes, uint8_t *decoded_bytes2, uint16_t n, uint8_t max_iterations, uint8_t crc_type, uint8_t F, time_stats_t *init_stats, time_stats_t *alpha_stats, time_stats_t *beta_stats, time_stats_t *gamma_stats, time_stats_t *ext_stats, time_stats_t *intl1_stats, time_stats_t *intl2_stats) { return max_iterations+1; }; void decoding_setmode (int mode) { switch (mode) { case MODE_DECODE_NONE: decoder8=nodecod; decoder16=nodecod; encoder=(encoder_if_t*)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; break; case MODE_DECODE_C: decoder16=(decoder_if_t*)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; decoder8=(decoder_if_t*)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; encoder=(encoder_if_t*)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; break; case MODE_DECODE_AVX2: decoder16=(decoder_if_t*)shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fptr; decoder8=(decoder_if_t*)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; encoder=(encoder_if_t*)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; break; default: mode=MODE_DECODE_SSE; case MODE_DECODE_SSE: decoder8=(decoder_if_t*)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; decoder16=(decoder_if_t*)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr; encoder=(encoder_if_t*)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; break; } curmode=mode; } int load_codinglib(void) { int ret; memset(shlib_fdesc,0,sizeof(shlib_fdesc)); shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fname = "init_td8"; shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fname= "init_td16"; shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fname="init_td16avx2"; shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder8"; shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16"; shlib_fdesc[DECODE_TD_C_FPTRIDX].fname= "phy_threegpplte_turbo_decoder_scalar"; shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16avx2"; shlib_fdesc[DECODE_FREETD8_FPTRIDX].fname = "free_td8"; shlib_fdesc[DECODE_FREETD16_FPTRIDX].fname= "free_td16"; shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fname= "free_td16avx2"; shlib_fdesc[ENCODE_SSE_FPTRIDX].fname= "threegpplte_turbo_encoder_sse"; shlib_fdesc[ENCODE_C_FPTRIDX].fname= "threegpplte_turbo_encoder"; shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fname= "init_encoder_sse"; ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR,NULL); if (ret < 0) exit_fun("Error loading coding library"); /* execute encoder/decoder init functions */ shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fptr(); shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fptr(); if(shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr != NULL) { shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr(); } if(shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr != NULL) { shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr(); } decoding_setmode(MODE_DECODE_SSE); /* look for telnet server, if it is loaded, add the coding commands to it */ add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); if (addcmd != NULL) { addcmd("coding",coding_vardef,coding_cmdarray); } return 0; } void free_codinglib(void) { shlib_fdesc[DECODE_FREETD8_FPTRIDX].fptr(); shlib_fdesc[DECODE_FREETD16_FPTRIDX].fptr(); shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fptr(); } /* functions for telnet support, when telnet server is loaded */ int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) { if (debug > 0) prnt( "coding_setmod_cmd received %s\n",buff); if (strcasestr(buff,"sse") != NULL) { decoding_setmode(MODE_DECODE_SSE); } else if (strcasestr(buff,"avx2") != NULL) { decoding_setmode(MODE_DECODE_AVX2); } else if (strcasestr(buff,"stdc") != NULL) { decoding_setmode(MODE_DECODE_C); } else if (strcasestr(buff,"none") != NULL) { decoding_setmode(MODE_DECODE_NONE); } else { prnt("%s: wrong setmod parameter...\n",buff); } prnt("Coding and decoding current mode: %s\n",modedesc[curmode]); return 0; }